diff options
author | Pablo Neira <pablo@netfilter.org> | 2013-06-03 05:28:43 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-06-04 20:26:49 -0400 |
commit | 5e71d9d77c07fa7d4c42287a177f7b738d0cd4b9 (patch) | |
tree | 143f0f3ea5dbebf7bee5e326c73002f36d87dbb3 | |
parent | 9bc297ea0622bb2a6b3abfa2fa84f0a3b86ef8c8 (diff) |
net: fix sk_buff head without data area
Eric Dumazet spotted that we have to check skb->head instead
of skb->data as skb->head points to the beginning of the
data area of the skbuff. Similarly, we have to initialize the
skb->head pointer, not skb->data in __alloc_skb_head.
After this fix, netlink crashes in the release path of the
sk_buff, so let's fix that as well.
This bug was introduced in (0ebd0ac net: add function to
allocate sk_buff head without data area).
Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/core/skbuff.c | 4 | ||||
-rw-r--r-- | net/netlink/af_netlink.c | 2 |
2 files changed, 3 insertions, 3 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index af9185d0be6a..cfd777bd6bd0 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -195,7 +195,7 @@ struct sk_buff *__alloc_skb_head(gfp_t gfp_mask, int node) | |||
195 | * the tail pointer in struct sk_buff! | 195 | * the tail pointer in struct sk_buff! |
196 | */ | 196 | */ |
197 | memset(skb, 0, offsetof(struct sk_buff, tail)); | 197 | memset(skb, 0, offsetof(struct sk_buff, tail)); |
198 | skb->data = NULL; | 198 | skb->head = NULL; |
199 | skb->truesize = sizeof(struct sk_buff); | 199 | skb->truesize = sizeof(struct sk_buff); |
200 | atomic_set(&skb->users, 1); | 200 | atomic_set(&skb->users, 1); |
201 | 201 | ||
@@ -611,7 +611,7 @@ static void skb_release_head_state(struct sk_buff *skb) | |||
611 | static void skb_release_all(struct sk_buff *skb) | 611 | static void skb_release_all(struct sk_buff *skb) |
612 | { | 612 | { |
613 | skb_release_head_state(skb); | 613 | skb_release_head_state(skb); |
614 | if (likely(skb->data)) | 614 | if (likely(skb->head)) |
615 | skb_release_data(skb); | 615 | skb_release_data(skb); |
616 | } | 616 | } |
617 | 617 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 12ac6b47a35c..d0b3dd60d386 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -747,7 +747,7 @@ static void netlink_skb_destructor(struct sk_buff *skb) | |||
747 | atomic_dec(&ring->pending); | 747 | atomic_dec(&ring->pending); |
748 | sock_put(sk); | 748 | sock_put(sk); |
749 | 749 | ||
750 | skb->data = NULL; | 750 | skb->head = NULL; |
751 | } | 751 | } |
752 | #endif | 752 | #endif |
753 | if (skb->sk != NULL) | 753 | if (skb->sk != NULL) |