]>
Commit | Line | Data |
---|---|---|
28cd9a8f GKH |
1 | From aa0dfee5c6f808526f4ca425343a4f95a7c5e6ad Mon Sep 17 00:00:00 2001 |
2 | From: Eric Dumazet <edumazet@google.com> | |
3 | Date: Mon, 22 Oct 2012 09:03:40 +0000 | |
4 | Subject: net: fix secpath kmemleak | |
5 | ||
6 | ||
7 | From: Eric Dumazet <edumazet@google.com> | |
8 | ||
9 | [ Upstream commit 3d861f661006606bf159fd6bd973e83dbf21d0f9 ] | |
10 | ||
11 | Mike Kazantsev found 3.5 kernels and beyond were leaking memory, | |
12 | and tracked the faulty commit to a1c7fff7e18f59e ("net: | |
13 | netdev_alloc_skb() use build_skb()") | |
14 | ||
15 | While this commit seems fine, it uncovered a bug introduced | |
16 | in commit bad43ca8325 ("net: introduce skb_try_coalesce()), in function | |
17 | kfree_skb_partial()"): | |
18 | ||
19 | If head is stolen, we free the sk_buff, | |
20 | without removing references on secpath (skb->sp). | |
21 | ||
22 | So IPsec + IP defrag/reassembly (using skb coalescing), or | |
23 | TCP coalescing could leak secpath objects. | |
24 | ||
25 | Fix this bug by calling skb_release_head_state(skb) to properly | |
26 | release all possible references to linked objects. | |
27 | ||
28 | Reported-by: Mike Kazantsev <mk.fraggod@gmail.com> | |
29 | Signed-off-by: Eric Dumazet <edumazet@google.com> | |
30 | Bisected-by: Mike Kazantsev <mk.fraggod@gmail.com> | |
31 | Tested-by: Mike Kazantsev <mk.fraggod@gmail.com> | |
32 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
33 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
34 | --- | |
35 | net/core/skbuff.c | 6 ++++-- | |
36 | 1 file changed, 4 insertions(+), 2 deletions(-) | |
37 | ||
38 | --- a/net/core/skbuff.c | |
39 | +++ b/net/core/skbuff.c | |
40 | @@ -3384,10 +3384,12 @@ EXPORT_SYMBOL(__skb_warn_lro_forwarding) | |
41 | ||
42 | void kfree_skb_partial(struct sk_buff *skb, bool head_stolen) | |
43 | { | |
44 | - if (head_stolen) | |
45 | + if (head_stolen) { | |
46 | + skb_release_head_state(skb); | |
47 | kmem_cache_free(skbuff_head_cache, skb); | |
48 | - else | |
49 | + } else { | |
50 | __kfree_skb(skb); | |
51 | + } | |
52 | } | |
53 | EXPORT_SYMBOL(kfree_skb_partial); | |
54 |