aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/skbuff.h
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2005-07-05 14:08:10 -0700
committerDavid S. Miller <davem@davemloft.net>2005-07-05 14:08:10 -0700
commit55820ee2f8c767a2833b21bd365e5753f50bd8ce (patch)
treefbf89b8f1365c18c5c2ee0fad15f61f6f3127af8 /include/linux/skbuff.h
parent[PATCH] ARM: Fix new-ABI layout of struct stat64 (diff)
downloadlinux-dev-55820ee2f8c767a2833b21bd365e5753f50bd8ce.tar.xz
linux-dev-55820ee2f8c767a2833b21bd365e5753f50bd8ce.zip
[NET]: Fix signedness issues in net/core/filter.c
This is the code to load packet data into a register: k = fentry->k; if (k < 0) { ... } else { u32 _tmp, *p; p = skb_header_pointer(skb, k, 4, &_tmp); if (p != NULL) { A = ntohl(*p); continue; } } skb_header_pointer checks if the requested data is within the linear area: int hlen = skb_headlen(skb); if (offset + len <= hlen) return skb->data + offset; When offset is within [INT_MAX-len+1..INT_MAX] the addition will result in a negative number which is <= hlen. I couldn't trigger a crash on my AMD64 with 2GB of memory, but a coworker tried on his x86 machine and it crashed immediately. This patch fixes the check in skb_header_pointer to handle large positive offsets similar to skb_copy_bits. Invalid data can still be accessed using negative offsets (also similar to skb_copy_bits), anyone using negative offsets needs to verify them himself. Thanks to Thomas Vögtle <thomas.voegtle@coreworks.de> for verifying the problem by crashing his machine and providing me with an Oops. Signed-off-by: Patrick McHardy <kaber@trash.net> Acked-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/skbuff.h')
-rw-r--r--include/linux/skbuff.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 416a2e4024b2..fbcb18651970 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1211,7 +1211,7 @@ static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
{
int hlen = skb_headlen(skb);
- if (offset + len <= hlen)
+ if (hlen - offset >= len)
return skb->data + offset;
if (skb_copy_bits(skb, offset, buffer, len) < 0)