patch-2.4.4 linux/net/core/filter.c

Next file: linux/net/core/iovec.c
Previous file: linux/net/core/dev.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.3/linux/net/core/filter.c linux/net/core/filter.c
@@ -72,7 +72,7 @@
 	/* len is UNSIGNED. Byte wide insns relies only on implicit
 	   type casts to prevent reading arbitrary memory locations.
 	 */
-	unsigned int len = skb->len;
+	unsigned int len = skb->len-skb->data_len;
 	struct sock_filter *fentry;	/* We walk down these */
 	u32 A = 0;	   		/* Accumulator */
 	u32 X = 0;   			/* Index Register */
@@ -201,7 +201,7 @@
 			case BPF_LD|BPF_W|BPF_ABS:
 				k = fentry->k;
 load_w:
-				if(k+sizeof(u32) <= len) {
+				if(k >= 0 && (unsigned int)(k+sizeof(u32)) <= len) {
 					A = ntohl(*(u32*)&data[k]);
 					continue;
 				}
@@ -214,13 +214,19 @@
 						A = ntohl(*(u32*)ptr);
 						continue;
 					}
+				} else {
+					u32 tmp;
+					if (!skb_copy_bits(skb, k, &tmp, 4)) {
+						A = ntohl(tmp);
+						continue;
+					}
 				}
 				return 0;
 
 			case BPF_LD|BPF_H|BPF_ABS:
 				k = fentry->k;
 load_h:
-				if(k + sizeof(u16) <= len) {
+				if(k >= 0 && (unsigned int) (k + sizeof(u16)) <= len) {
 					A = ntohs(*(u16*)&data[k]);
 					continue;
 				}
@@ -233,13 +239,19 @@
 						A = ntohs(*(u16*)ptr);
 						continue;
 					}
+				} else {
+					u16 tmp;
+					if (!skb_copy_bits(skb, k, &tmp, 2)) {
+						A = ntohs(tmp);
+						continue;
+					}
 				}
 				return 0;
 
 			case BPF_LD|BPF_B|BPF_ABS:
 				k = fentry->k;
 load_b:
-				if(k < len) {
+				if(k >= 0 && (unsigned int)k < len) {
 					A = data[k];
 					continue;
 				}
@@ -252,6 +264,12 @@
 						A = *ptr;
 						continue;
 					}
+				} else {
+					u8 tmp;
+					if (!skb_copy_bits(skb, k, &tmp, 1)) {
+						A = tmp;
+						continue;
+					}
 				}
 				return 0;
 
@@ -277,7 +295,7 @@
 
 			case BPF_LDX|BPF_B|BPF_MSH:
 				k = fentry->k;
-				if(k >= len)
+				if(k >= 0 && (unsigned int)k >= len)
 					return (0);
 				X = (data[k] & 0xf) << 2;
 				continue;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)