diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2008-12-26 17:57:42 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-12-26 17:57:42 -0500 |
commit | 0da2afd59653d2edf5c8e0f09b23f367ab5bc80f (patch) | |
tree | d6dad9cf3ca8a352409b5ce5e8e2445434aa00f5 | |
parent | 843813453f52e3378fc988c8364063fd4cb9d0e3 (diff) |
gro: Fix potential use after free
The initial skb may have been freed after napi_gro_complete in
napi_gro_receive if it was merged into an existing packet. Thus
we cannot check same_flow (which indicates whether it was merged)
after calling napi_gro_complete.
This patch fixes this by saving the same_flow status before the
call to napi_gro_complete.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/core/dev.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 536a8ac189c8..303e984ee6a6 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2390,6 +2390,7 @@ int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | |||
2390 | __be16 type = skb->protocol; | 2390 | __be16 type = skb->protocol; |
2391 | struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK]; | 2391 | struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK]; |
2392 | int count = 0; | 2392 | int count = 0; |
2393 | int same_flow; | ||
2393 | int mac_len; | 2394 | int mac_len; |
2394 | 2395 | ||
2395 | if (!(skb->dev->features & NETIF_F_GRO)) | 2396 | if (!(skb->dev->features & NETIF_F_GRO)) |
@@ -2425,6 +2426,8 @@ int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | |||
2425 | if (&ptype->list == head) | 2426 | if (&ptype->list == head) |
2426 | goto normal; | 2427 | goto normal; |
2427 | 2428 | ||
2429 | same_flow = NAPI_GRO_CB(skb)->same_flow; | ||
2430 | |||
2428 | if (pp) { | 2431 | if (pp) { |
2429 | struct sk_buff *nskb = *pp; | 2432 | struct sk_buff *nskb = *pp; |
2430 | 2433 | ||
@@ -2434,7 +2437,7 @@ int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | |||
2434 | count--; | 2437 | count--; |
2435 | } | 2438 | } |
2436 | 2439 | ||
2437 | if (NAPI_GRO_CB(skb)->same_flow) | 2440 | if (same_flow) |
2438 | goto ok; | 2441 | goto ok; |
2439 | 2442 | ||
2440 | if (NAPI_GRO_CB(skb)->flush || count >= MAX_GRO_SKBS) { | 2443 | if (NAPI_GRO_CB(skb)->flush || count >= MAX_GRO_SKBS) { |