diff options
Diffstat (limited to 'net/ipv6/output_core.c')
-rw-r--r-- | net/ipv6/output_core.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c index 1d184322a7b1..f9f02581c4ca 100644 --- a/net/ipv6/output_core.c +++ b/net/ipv6/output_core.c | |||
@@ -78,15 +78,15 @@ EXPORT_SYMBOL(ipv6_select_ident); | |||
78 | 78 | ||
79 | int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) | 79 | int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) |
80 | { | 80 | { |
81 | u16 offset = sizeof(struct ipv6hdr); | 81 | unsigned int offset = sizeof(struct ipv6hdr); |
82 | struct ipv6_opt_hdr *exthdr = | ||
83 | (struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1); | ||
84 | unsigned int packet_len = skb_tail_pointer(skb) - | 82 | unsigned int packet_len = skb_tail_pointer(skb) - |
85 | skb_network_header(skb); | 83 | skb_network_header(skb); |
86 | int found_rhdr = 0; | 84 | int found_rhdr = 0; |
87 | *nexthdr = &ipv6_hdr(skb)->nexthdr; | 85 | *nexthdr = &ipv6_hdr(skb)->nexthdr; |
88 | 86 | ||
89 | while (offset + 1 <= packet_len) { | 87 | while (offset <= packet_len) { |
88 | struct ipv6_opt_hdr *exthdr; | ||
89 | unsigned int len; | ||
90 | 90 | ||
91 | switch (**nexthdr) { | 91 | switch (**nexthdr) { |
92 | 92 | ||
@@ -107,13 +107,19 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) | |||
107 | return offset; | 107 | return offset; |
108 | } | 108 | } |
109 | 109 | ||
110 | offset += ipv6_optlen(exthdr); | 110 | if (offset + sizeof(struct ipv6_opt_hdr) > packet_len) |
111 | *nexthdr = &exthdr->nexthdr; | 111 | return -EINVAL; |
112 | |||
112 | exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) + | 113 | exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) + |
113 | offset); | 114 | offset); |
115 | len = ipv6_optlen(exthdr); | ||
116 | if (len + offset >= IPV6_MAXPLEN) | ||
117 | return -EINVAL; | ||
118 | offset += len; | ||
119 | *nexthdr = &exthdr->nexthdr; | ||
114 | } | 120 | } |
115 | 121 | ||
116 | return offset; | 122 | return -EINVAL; |
117 | } | 123 | } |
118 | EXPORT_SYMBOL(ip6_find_1stfragopt); | 124 | EXPORT_SYMBOL(ip6_find_1stfragopt); |
119 | 125 | ||