aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ipv6.h2
-rw-r--r--net/ipv6/exthdrs_core.c11
-rw-r--r--net/ipv6/icmp.c4
-rw-r--r--security/selinux/hooks.c3
4 files changed, 8 insertions, 12 deletions
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 87c45cbfbaf6..771b47e30f86 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -416,7 +416,7 @@ extern void ipv6_push_frag_opts(struct sk_buff *skb,
416 u8 *proto); 416 u8 *proto);
417 417
418extern int ipv6_skip_exthdr(const struct sk_buff *, int start, 418extern int ipv6_skip_exthdr(const struct sk_buff *, int start,
419 u8 *nexthdrp, int len); 419 u8 *nexthdrp);
420 420
421extern int ipv6_ext_hdr(u8 nexthdr); 421extern int ipv6_ext_hdr(u8 nexthdr);
422 422
diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c
index 6dda815c013f..315bc1fbec3f 100644
--- a/net/ipv6/exthdrs_core.c
+++ b/net/ipv6/exthdrs_core.c
@@ -41,8 +41,8 @@ int ipv6_ext_hdr(u8 nexthdr)
41 * when Linux implements ESP (and maybe AUTH) headers. 41 * when Linux implements ESP (and maybe AUTH) headers.
42 * --AK 42 * --AK
43 * 43 *
44 * This function parses (probably truncated) exthdr set "hdr" 44 * This function parses (probably truncated) exthdr set "hdr".
45 * of length "len". "nexthdrp" initially points to some place, 45 * "nexthdrp" initially points to some place,
46 * where type of the first header can be found. 46 * where type of the first header can be found.
47 * 47 *
48 * It skips all well-known exthdrs, and returns pointer to the start 48 * It skips all well-known exthdrs, and returns pointer to the start
@@ -63,7 +63,7 @@ int ipv6_ext_hdr(u8 nexthdr)
63 * --ANK (980726) 63 * --ANK (980726)
64 */ 64 */
65 65
66int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp, int len) 66int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp)
67{ 67{
68 u8 nexthdr = *nexthdrp; 68 u8 nexthdr = *nexthdrp;
69 69
@@ -71,13 +71,11 @@ int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp, int len
71 struct ipv6_opt_hdr _hdr, *hp; 71 struct ipv6_opt_hdr _hdr, *hp;
72 int hdrlen; 72 int hdrlen;
73 73
74 if (len < (int)sizeof(struct ipv6_opt_hdr))
75 return -1;
76 if (nexthdr == NEXTHDR_NONE) 74 if (nexthdr == NEXTHDR_NONE)
77 return -1; 75 return -1;
78 hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); 76 hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
79 if (hp == NULL) 77 if (hp == NULL)
80 BUG(); 78 return -1;
81 if (nexthdr == NEXTHDR_FRAGMENT) { 79 if (nexthdr == NEXTHDR_FRAGMENT) {
82 unsigned short _frag_off, *fp; 80 unsigned short _frag_off, *fp;
83 fp = skb_header_pointer(skb, 81 fp = skb_header_pointer(skb,
@@ -97,7 +95,6 @@ int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp, int len
97 hdrlen = ipv6_optlen(hp); 95 hdrlen = ipv6_optlen(hp);
98 96
99 nexthdr = hp->nexthdr; 97 nexthdr = hp->nexthdr;
100 len -= hdrlen;
101 start += hdrlen; 98 start += hdrlen;
102 } 99 }
103 100
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 87b9082ceab2..8e0f569b883e 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -135,7 +135,7 @@ static int is_ineligible(struct sk_buff *skb)
135 if (len < 0) 135 if (len < 0)
136 return 1; 136 return 1;
137 137
138 ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr, len); 138 ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr);
139 if (ptr < 0) 139 if (ptr < 0)
140 return 0; 140 return 0;
141 if (nexthdr == IPPROTO_ICMPV6) { 141 if (nexthdr == IPPROTO_ICMPV6) {
@@ -514,7 +514,7 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info)
514 nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr; 514 nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr;
515 if (ipv6_ext_hdr(nexthdr)) { 515 if (ipv6_ext_hdr(nexthdr)) {
516 /* now skip over extension headers */ 516 /* now skip over extension headers */
517 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr, skb->len - sizeof(struct ipv6hdr)); 517 inner_offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr);
518 if (inner_offset<0) 518 if (inner_offset<0)
519 return; 519 return;
520 } else { 520 } else {
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2ae7d3cb8df4..0d378141c95a 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2855,8 +2855,7 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, struct avc_audit_data *ad
2855 2855
2856 nexthdr = ip6->nexthdr; 2856 nexthdr = ip6->nexthdr;
2857 offset += sizeof(_ipv6h); 2857 offset += sizeof(_ipv6h);
2858 offset = ipv6_skip_exthdr(skb, offset, &nexthdr, 2858 offset = ipv6_skip_exthdr(skb, offset, &nexthdr);
2859 skb->tail - skb->head - offset);
2860 if (offset < 0) 2859 if (offset < 0)
2861 goto out; 2860 goto out;
2862 2861