summaryrefslogtreecommitdiff
blob: 633b37586e0068c234c43403110eeb5af2558620 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
diff --exclude-from=/home/dang/.diffrc -up -ruN linux-2.6.18-usermode-r1.orig/net/ipv6/netfilter/ip6_tables.c linux-2.6.18-usermode-r1/net/ipv6/netfilter/ip6_tables.c
--- linux-2.6.18-usermode-r1.orig/net/ipv6/netfilter/ip6_tables.c	2007-01-02 21:03:01.000000000 -0500
+++ linux-2.6.18-usermode-r1/net/ipv6/netfilter/ip6_tables.c	2007-01-02 23:02:56.000000000 -0500
@@ -1445,6 +1445,9 @@ static void __exit ip6_tables_fini(void)
  * If target header is found, its offset is set in *offset and return protocol
  * number. Otherwise, return -1.
  *
+ * If the first fragment doesn't contain the final protocol header or
+ * NEXTHDR_NONE it is considered invalid.
+ *
  * Note that non-1st fragment is special case that "the protocol number
  * of last header" is "next header" field in Fragment header. In this case,
  * *offset is meaningless and fragment offset is stored in *fragoff if fragoff
@@ -1468,12 +1471,12 @@ int ipv6_find_hdr(const struct sk_buff *
 		if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) {
 			if (target < 0)
 				break;
-			return -1;
+			return -ENOENT;
 		}
 
 		hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
 		if (hp == NULL)
-			return -1;
+			return -EBADMSG;
 		if (nexthdr == NEXTHDR_FRAGMENT) {
 			unsigned short _frag_off, *fp;
 			fp = skb_header_pointer(skb,
@@ -1482,7 +1485,7 @@ int ipv6_find_hdr(const struct sk_buff *
 						sizeof(_frag_off),
 						&_frag_off);
 			if (fp == NULL)
-				return -1;
+				return -EBADMSG;
 
 			_frag_off = ntohs(*fp) & ~0x7;
 			if (_frag_off) {
@@ -1493,7 +1496,7 @@ int ipv6_find_hdr(const struct sk_buff *
 						*fragoff = _frag_off;
 					return hp->nexthdr;
 				}
-				return -1;
+				return -ENOENT;
 			}
 			hdrlen = 8;
 		} else if (nexthdr == NEXTHDR_AUTH)
diff --exclude-from=/home/dang/.diffrc -up -ruN linux-2.6.18-usermode-r1.orig/net/ipv6/netfilter/ip6t_ah.c linux-2.6.18-usermode-r1/net/ipv6/netfilter/ip6t_ah.c
--- linux-2.6.18-usermode-r1.orig/net/ipv6/netfilter/ip6t_ah.c	2006-09-19 23:42:06.000000000 -0400
+++ linux-2.6.18-usermode-r1/net/ipv6/netfilter/ip6t_ah.c	2007-01-02 23:03:50.000000000 -0500
@@ -54,9 +54,14 @@ match(const struct sk_buff *skb,
 	const struct ip6t_ah *ahinfo = matchinfo;
 	unsigned int ptr;
 	unsigned int hdrlen = 0;
-
-	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL) < 0)
-		return 0;
+	int err;
+  
+	err = ipv6_find_hdr(skb, &amp;ptr, NEXTHDR_AUTH, NULL);
+	if (err &lt; 0) {
+		if (err != -ENOENT)
+			*hotdrop = 1;
+  		return 0;
+	}
 
 	ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
 	if (ah == NULL) {
diff --exclude-from=/home/dang/.diffrc -up -ruN linux-2.6.18-usermode-r1.orig/net/ipv6/netfilter/ip6t_frag.c linux-2.6.18-usermode-r1/net/ipv6/netfilter/ip6t_frag.c
--- linux-2.6.18-usermode-r1.orig/net/ipv6/netfilter/ip6t_frag.c	2006-09-19 23:42:06.000000000 -0400
+++ linux-2.6.18-usermode-r1/net/ipv6/netfilter/ip6t_frag.c	2007-01-02 23:04:29.000000000 -0500
@@ -52,9 +52,14 @@ match(const struct sk_buff *skb,
 	struct frag_hdr _frag, *fh;
 	const struct ip6t_frag *fraginfo = matchinfo;
 	unsigned int ptr;
-
-	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0)
-		return 0;
+	int err;
+  
+	err = ipv6_find_hdr(skb, &amp;ptr, NEXTHDR_FRAGMENT, NULL);
+	if (err &lt; 0) {
+		if (err != -ENOENT)
+			*hotdrop = 1;
+  		return 0;
+	}
 
 	fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
 	if (fh == NULL) {
diff --exclude-from=/home/dang/.diffrc -up -ruN linux-2.6.18-usermode-r1.orig/net/ipv6/netfilter/ip6t_rt.c linux-2.6.18-usermode-r1/net/ipv6/netfilter/ip6t_rt.c
--- linux-2.6.18-usermode-r1.orig/net/ipv6/netfilter/ip6t_rt.c	2006-09-19 23:42:06.000000000 -0400
+++ linux-2.6.18-usermode-r1/net/ipv6/netfilter/ip6t_rt.c	2007-01-02 23:04:53.000000000 -0500
@@ -58,9 +58,14 @@ match(const struct sk_buff *skb,
 	unsigned int hdrlen = 0;
 	unsigned int ret = 0;
 	struct in6_addr *ap, _addr;
-
-	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0)
-		return 0;
+	int err;
+  
+	err = ipv6_find_hdr(skb, &amp;ptr, NEXTHDR_ROUTING, NULL);
+	if (err &lt; 0) {
+		if (err != -ENOENT)
+			*hotdrop = 1;
+  		return 0;
+	}
 
 	rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
 	if (rh == NULL) {