From 3d861f661006606bf159fd6bd973e83dbf21d0f9 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 22 Oct 2012 09:03:40 +0000 Subject: net: fix secpath kmemleak Mike Kazantsev found 3.5 kernels and beyond were leaking memory, and tracked the faulty commit to a1c7fff7e18f59e ("net: netdev_alloc_skb() use build_skb()") While this commit seems fine, it uncovered a bug introduced in commit bad43ca8325 ("net: introduce skb_try_coalesce()), in function kfree_skb_partial()"): If head is stolen, we free the sk_buff, without removing references on secpath (skb->sp). So IPsec + IP defrag/reassembly (using skb coalescing), or TCP coalescing could leak secpath objects. Fix this bug by calling skb_release_head_state(skb) to properly release all possible references to linked objects. Reported-by: Mike Kazantsev Signed-off-by: Eric Dumazet Bisected-by: Mike Kazantsev Tested-by: Mike Kazantsev Signed-off-by: David S. Miller --- net/core/skbuff.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'net/core') diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 6e04b1fa11f2..4007c1437fda 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -3379,10 +3379,12 @@ EXPORT_SYMBOL(__skb_warn_lro_forwarding); void kfree_skb_partial(struct sk_buff *skb, bool head_stolen) { - if (head_stolen) + if (head_stolen) { + skb_release_head_state(skb); kmem_cache_free(skbuff_head_cache, skb); - else + } else { __kfree_skb(skb); + } } EXPORT_SYMBOL(kfree_skb_partial); -- cgit v1.2.3-71-gd317 From a7a558fe426adf22b0b979705167146bf16c37fa Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Thu, 1 Nov 2012 16:23:10 +0000 Subject: rtnetlink: Use nlmsg type RTM_NEWNEIGH from dflt fdb dump Change the dflt fdb dump handler to use RTM_NEWNEIGH to be compatible with bridge dump routines. The dump reply from the network driver handlers should match the reply from bridge handler. The fact they were not in the ixgbe case was effectively a bug. This patch resolves it. Applications that were not checking the nlmsg type will continue to work. And now applications that do check the type will work as expected. Signed-off-by: John Fastabend Signed-off-by: David S. Miller --- net/core/rtnetlink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net/core') diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 76d4c2c3c89b..fad649ae4dec 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -2192,7 +2192,8 @@ static int nlmsg_populate_fdb(struct sk_buff *skb, goto skip; err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, - portid, seq, 0, NTF_SELF); + portid, seq, + RTM_NEWNEIGH, NTF_SELF); if (err < 0) return err; skip: -- cgit v1.2.3-71-gd317 From a3d744e995d2b936c500585ae39d99ee251c89b4 Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Tue, 6 Nov 2012 02:10:10 +0000 Subject: af-packet: fix oops when socket is not present MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Due to a NULL dereference, the following patch is causing oops in normal trafic condition: commit c0de08d04215031d68fa13af36f347a6cfa252ca Author: Eric Leblond Date:   Thu Aug 16 22:02:58 2012 +0000     af_packet: don't emit packet on orig fanout group This buggy patch was a feature fix and has reached most stable branches. When skb->sk is NULL and when packet fanout is used, there is a crash in match_fanout_group where skb->sk is accessed. This patch fixes the issue by returning false as soon as the socket is NULL: this correspond to the wanted behavior because the kernel as to resend the skb to all the listening socket in this case. Signed-off-by: Eric Leblond Signed-off-by: David S. Miller --- net/core/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net/core') diff --git a/net/core/dev.c b/net/core/dev.c index 09cb3f6dc40c..bda6d004f9f0 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1666,7 +1666,7 @@ static inline int deliver_skb(struct sk_buff *skb, static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) { - if (ptype->af_packet_priv == NULL) + if (!ptype->af_packet_priv || !skb->sk) return false; if (ptype->id_match) -- cgit v1.2.3-71-gd317 From a652208e0b52c190e57f2a075ffb5e897fe31c3b Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 14 Nov 2012 02:51:04 +0000 Subject: net: correct check in dev_addr_del() Check (ha->addr == dev->dev_addr) is always true because dev_addr_init() sets this. Correct the check to behave properly on addr removal. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/core/dev_addr_lists.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net/core') diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index 87cc17db2d56..b079c7bbc157 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c @@ -319,7 +319,8 @@ int dev_addr_del(struct net_device *dev, const unsigned char *addr, */ ha = list_first_entry(&dev->dev_addrs.list, struct netdev_hw_addr, list); - if (ha->addr == dev->dev_addr && ha->refcount == 1) + if (!memcmp(ha->addr, addr, dev->addr_len) && + ha->type == addr_type && ha->refcount == 1) return -ENOENT; err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, -- cgit v1.2.3-71-gd317 From baefa31db2f2b13a05d1b81bdf2d20d487f58b0a Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Fri, 16 Nov 2012 09:04:15 +0000 Subject: net-rps: Fix brokeness causing OOO packets In commit c445477d74ab3779 which adds aRFS to the kernel, the CPU selected for RFS is not set correctly when CPU is changing. This is causing OOO packets and probably other issues. Signed-off-by: Tom Herbert Acked-by: Eric Dumazet Acked-by: Ben Hutchings Signed-off-by: David S. Miller --- net/core/dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'net/core') diff --git a/net/core/dev.c b/net/core/dev.c index bda6d004f9f0..c0946cb2b354 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2818,8 +2818,10 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, if (unlikely(tcpu != next_cpu) && (tcpu == RPS_NO_CPU || !cpu_online(tcpu) || ((int)(per_cpu(softnet_data, tcpu).input_queue_head - - rflow->last_qtail)) >= 0)) + rflow->last_qtail)) >= 0)) { + tcpu = next_cpu; rflow = set_rps_cpu(dev, skb, rflow, next_cpu); + } if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) { *rflowp = rflow; -- cgit v1.2.3-71-gd317 From 38c1a01cf10c6e4049b4ffbd4a6af655df2a46e1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 16 Nov 2012 20:46:19 +0100 Subject: wireless: add back sysfs directory commit 35b2a113cb0298d4f9a1263338b456094a414057 broke (at least) Fedora's networking scripts, they check for the existence of the wireless directory. As the files aren't used, add the directory back and not the files. Also do it for both drivers based on the old wireless extensions and cfg80211, regardless of whether the compat code for wext is built into cfg80211 or not. Cc: stable@vger.kernel.org [3.6] Reported-by: Dave Airlie Reported-by: Bill Nottingham Signed-off-by: Johannes Berg --- net/core/net-sysfs.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'net/core') diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index bcf02f608cbf..017a8bacfb27 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -429,6 +429,17 @@ static struct attribute_group netstat_group = { .name = "statistics", .attrs = netstat_attrs, }; + +#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) +static struct attribute *wireless_attrs[] = { + NULL +}; + +static struct attribute_group wireless_group = { + .name = "wireless", + .attrs = wireless_attrs, +}; +#endif #endif /* CONFIG_SYSFS */ #ifdef CONFIG_RPS @@ -1409,6 +1420,15 @@ int netdev_register_kobject(struct net_device *net) groups++; *groups++ = &netstat_group; + +#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) + if (net->ieee80211_ptr) + *groups++ = &wireless_group; +#if IS_ENABLED(CONFIG_WIRELESS_EXT) + else if (net->wireless_handlers) + *groups++ = &wireless_group; +#endif +#endif #endif /* CONFIG_SYSFS */ error = device_add(dev); -- cgit v1.2.3-71-gd317 From c3c7c254b2e8cd99b0adf288c2a1bddacd7ba255 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 6 Dec 2012 13:54:59 +0000 Subject: net: gro: fix possible panic in skb_gro_receive() commit 2e71a6f8084e (net: gro: selective flush of packets) added a bug for skbs using frag_list. This part of the GRO stack is rarely used, as it needs skb not using a page fragment for their skb->head. Most drivers do use a page fragment, but some of them use GFP_KERNEL allocations for the initial fill of their RX ring buffer. napi_gro_flush() overwrite skb->prev that was used for these skb to point to the last skb in frag_list. Fix this using a separate field in struct napi_gro_cb to point to the last fragment. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/netdevice.h | 3 +++ net/core/dev.c | 2 ++ net/core/skbuff.c | 6 +++--- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'net/core') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index f8eda0276f03..a848ffc327f4 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1488,6 +1488,9 @@ struct napi_gro_cb { /* Used in ipv6_gro_receive() */ int proto; + + /* used in skb_gro_receive() slow path */ + struct sk_buff *last; }; #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb) diff --git a/net/core/dev.c b/net/core/dev.c index c0946cb2b354..e5942bf45a6d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3451,6 +3451,8 @@ static int napi_gro_complete(struct sk_buff *skb) struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK]; int err = -ENOENT; + BUILD_BUG_ON(sizeof(struct napi_gro_cb) > sizeof(skb->cb)); + if (NAPI_GRO_CB(skb)->count == 1) { skb_shinfo(skb)->gso_size = 0; goto out; diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 4007c1437fda..3f0636cd76cd 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -3004,7 +3004,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) skb_shinfo(nskb)->gso_size = pinfo->gso_size; pinfo->gso_size = 0; skb_header_release(p); - nskb->prev = p; + NAPI_GRO_CB(nskb)->last = p; nskb->data_len += p->len; nskb->truesize += p->truesize; @@ -3030,8 +3030,8 @@ merge: __skb_pull(skb, offset); - p->prev->next = skb; - p->prev = skb; + NAPI_GRO_CB(p)->last->next = skb; + NAPI_GRO_CB(p)->last = skb; skb_header_release(skb); done: -- cgit v1.2.3-71-gd317