diff options
-rw-r--r-- | include/net/ipv6.h | 2 | ||||
-rw-r--r-- | net/ipv6/exthdrs_core.c | 11 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 4 | ||||
-rw-r--r-- | security/selinux/hooks.c | 3 |
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 | ||
418 | extern int ipv6_skip_exthdr(const struct sk_buff *, int start, | 418 | extern int ipv6_skip_exthdr(const struct sk_buff *, int start, |
419 | u8 *nexthdrp, int len); | 419 | u8 *nexthdrp); |
420 | 420 | ||
421 | extern int ipv6_ext_hdr(u8 nexthdr); | 421 | extern 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 | ||
66 | int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp, int len) | 66 | int 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 | ||