Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1764771AbYCUXAh (ORCPT ); Fri, 21 Mar 2008 19:00:37 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1756214AbYCUWuz (ORCPT ); Fri, 21 Mar 2008 18:50:55 -0400 Received: from 216-99-217-87.dsl.aracnet.com ([216.99.217.87]:59312 "EHLO sous-sol.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1763739AbYCUWuw (ORCPT ); Fri, 21 Mar 2008 18:50:52 -0400 Message-Id: <20080321224408.967850935@sous-sol.org> References: <20080321224250.144333319@sous-sol.org> User-Agent: quilt/0.46-1 Date: Fri, 21 Mar 2008 15:43:28 -0700 From: Chris Wright To: linux-kernel@vger.kernel.org, stable@kernel.org Cc: Justin Forbes , Zwane Mwaikambo , "Theodore Ts'o" , Randy Dunlap , Dave Jones , Chuck Wolber , Chris Wedgwood , Michael Krufky , Chuck Ebbert , Domenico Andreoli , torvalds@linux-foundation.org, akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk, Patrick McHardy , netfilter-devel@vger.kernel.org, davem@davemloft.net, Greg Kroah-Hartman Subject: [patch 38/76] NETFILTER: nfnetlink_queue: fix SKB_LINEAR_ASSERT when mangling packet data Content-Disposition: inline; filename=netfilter-nfnetlink_queue-fix-skb_linear_assert-when-mangling-packet-data.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3937 Lines: 134 -stable review patch. If anyone has any objections, please let us know. --------------------- From: Patrick McHardy Upstream commit e2b58a67: As reported by Tomas Simonaitis , inserting new data in skbs queued over {ip,ip6,nfnetlink}_queue triggers a SKB_LINEAR_ASSERT in skb_put(). Going back through the git history, it seems this bug is present since at least 2.6.12-rc2, probably even since the removal of skb_linearize() for netfilter. Linearize non-linear skbs through skb_copy_expand() when enlarging them. Tested by Thomas, fixes bugzilla #9933. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller Signed-off-by: Chris Wright Signed-off-by: Greg Kroah-Hartman --- Patrick, which part of commit log did you want to drop? net/ipv4/netfilter/ip_queue.c | 12 +++++++----- net/ipv6/netfilter/ip6_queue.c | 10 ++++++---- net/netfilter/nfnetlink_queue.c | 10 ++++++---- 3 files changed, 19 insertions(+), 13 deletions(-) --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c @@ -336,8 +336,8 @@ static int ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) { int diff; - int err; struct iphdr *user_iph = (struct iphdr *)v->payload; + struct sk_buff *nskb; if (v->data_len < sizeof(*user_iph)) return 0; @@ -349,14 +349,16 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, st if (v->data_len > 0xFFFF) return -EINVAL; if (diff > skb_tailroom(e->skb)) { - err = pskb_expand_head(e->skb, 0, + nskb = skb_copy_expand(e->skb, 0, diff - skb_tailroom(e->skb), GFP_ATOMIC); - if (err) { + if (!nskb) { printk(KERN_WARNING "ip_queue: error " - "in mangle, dropping packet: %d\n", -err); - return err; + "in mangle, dropping packet\n"); + return -ENOMEM; } + kfree_skb(e->skb); + e->skb = nskb; } skb_put(e->skb, diff); } --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c @@ -333,8 +333,8 @@ static int ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) { int diff; - int err; struct ipv6hdr *user_iph = (struct ipv6hdr *)v->payload; + struct sk_buff *nskb; if (v->data_len < sizeof(*user_iph)) return 0; @@ -346,14 +346,16 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, st if (v->data_len > 0xFFFF) return -EINVAL; if (diff > skb_tailroom(e->skb)) { - err = pskb_expand_head(e->skb, 0, + nskb = skb_copy_expand(e->skb, 0, diff - skb_tailroom(e->skb), GFP_ATOMIC); - if (err) { + if (!nskb) { printk(KERN_WARNING "ip6_queue: OOM " "in mangle, dropping packet\n"); - return err; + return -ENOMEM; } + kfree_skb(e->skb); + e->skb = nskb; } skb_put(e->skb, diff); } --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -616,8 +616,8 @@ err_out_put: static int nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e) { + struct sk_buff *nskb; int diff; - int err; diff = data_len - e->skb->len; if (diff < 0) { @@ -627,14 +627,16 @@ nfqnl_mangle(void *data, int data_len, s if (data_len > 0xFFFF) return -EINVAL; if (diff > skb_tailroom(e->skb)) { - err = pskb_expand_head(e->skb, 0, + nskb = skb_copy_expand(e->skb, 0, diff - skb_tailroom(e->skb), GFP_ATOMIC); - if (err) { + if (!nskb) { printk(KERN_WARNING "nf_queue: OOM " "in mangle, dropping packet\n"); - return err; + return -ENOMEM; } + kfree_skb(e->skb); + e->skb = nskb; } skb_put(e->skb, diff); } -- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/