diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2008-12-26 14:57:42 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-12-26 14:57:42 -0800 |
commit | 0da2afd59653d2edf5c8e0f09b23f367ab5bc80f (patch) | |
tree | d6dad9cf3ca8a352409b5ce5e8e2445434aa00f5 /net | |
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>
Diffstat (limited to '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) __be16 type = skb->protocol; struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK]; int count = 0; + int same_flow; int mac_len; if (!(skb->dev->features & NETIF_F_GRO)) @@ -2425,6 +2426,8 @@ int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) if (&ptype->list == head) goto normal; + same_flow = NAPI_GRO_CB(skb)->same_flow; + if (pp) { struct sk_buff *nskb = *pp; @@ -2434,7 +2437,7 @@ int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) count--; } - if (NAPI_GRO_CB(skb)->same_flow) + if (same_flow) goto ok; if (NAPI_GRO_CB(skb)->flush || count >= MAX_GRO_SKBS) { |