Patchwork [net-next-2.6] filter: use size of fetched data in __load_pointer()

login
register
mail settings
Submitter Eric Dumazet
Date Dec. 8, 2010, 8:26 a.m.
Message ID <1291796775.2883.21.camel@edumazet-laptop>
Download mbox | patch
Permalink /patch/74650/
State Accepted
Delegated to: David Miller
Headers show

Comments

Eric Dumazet - Dec. 8, 2010, 8:26 a.m.
__load_pointer() checks data we fetch from skb is included in head
portion, but assumes we fetch one byte, instead of up to four.

This wont crash because we have extra bytes (struct skb_shared_info)
after head, but this can read uninitialized bytes.

Fix this using size of the data (1, 2, 4 bytes) in the test.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller - Dec. 10, 2010, 4:46 a.m.
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 08 Dec 2010 09:26:15 +0100

> __load_pointer() checks data we fetch from skb is included in head
> portion, but assumes we fetch one byte, instead of up to four.
> 
> This wont crash because we have extra bytes (struct skb_shared_info)
> after head, but this can read uninitialized bytes.
> 
> Fix this using size of the data (1, 2, 4 bytes) in the test.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

I'll apply this, thanks Eric.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/net/core/filter.c b/net/core/filter.c
index 25500f1..a57991e 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -88,7 +88,7 @@  enum {
 };
 
 /* No hurry in this branch */
-static void *__load_pointer(const struct sk_buff *skb, int k)
+static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size)
 {
 	u8 *ptr = NULL;
 
@@ -97,7 +97,7 @@  static void *__load_pointer(const struct sk_buff *skb, int k)
 	else if (k >= SKF_LL_OFF)
 		ptr = skb_mac_header(skb) + k - SKF_LL_OFF;
 
-	if (ptr >= skb->head && ptr < skb_tail_pointer(skb))
+	if (ptr >= skb->head && ptr + size <= skb_tail_pointer(skb))
 		return ptr;
 	return NULL;
 }
@@ -110,7 +110,7 @@  static inline void *load_pointer(const struct sk_buff *skb, int k,
 	else {
 		if (k >= SKF_AD_OFF)
 			return NULL;
-		return __load_pointer(skb, k);
+		return __load_pointer(skb, k, size);
 	}
 }