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 | ||
