aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2008-12-26 17:57:42 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-26 17:57:42 -0500
commit0da2afd59653d2edf5c8e0f09b23f367ab5bc80f (patch)
treed6dad9cf3ca8a352409b5ce5e8e2445434aa00f5
parent843813453f52e3378fc988c8364063fd4cb9d0e3 (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.c5
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) {