Skip to content

Commit f09db75

Browse files
qsngregkh
authored andcommitted
ipv6: avoid overflow of offset in ip6_find_1stfragopt
[ Upstream commit 6399f1fae4ec29fab5ec76070435555e256ca3a6 ] In some cases, offset can overflow and can cause an infinite loop in ip6_find_1stfragopt(). Make it unsigned int to prevent the overflow, and cap it at IPV6_MAXPLEN, since packets larger than that should be invalid. This problem has been here since before the beginning of git history. Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent e9b2f46 commit f09db75

1 file changed

Lines changed: 6 additions & 2 deletions

File tree

net/ipv6/output_core.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,15 @@ EXPORT_SYMBOL(ipv6_select_ident);
7878

7979
int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
8080
{
81-
u16 offset = sizeof(struct ipv6hdr);
81+
unsigned int offset = sizeof(struct ipv6hdr);
8282
unsigned int packet_len = skb_tail_pointer(skb) -
8383
skb_network_header(skb);
8484
int found_rhdr = 0;
8585
*nexthdr = &ipv6_hdr(skb)->nexthdr;
8686

8787
while (offset <= packet_len) {
8888
struct ipv6_opt_hdr *exthdr;
89+
unsigned int len;
8990

9091
switch (**nexthdr) {
9192

@@ -111,7 +112,10 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
111112

112113
exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
113114
offset);
114-
offset += ipv6_optlen(exthdr);
115+
len = ipv6_optlen(exthdr);
116+
if (len + offset >= IPV6_MAXPLEN)
117+
return -EINVAL;
118+
offset += len;
115119
*nexthdr = &exthdr->nexthdr;
116120
}
117121

0 commit comments

Comments
 (0)