Commit f09db755 authored by Sabrina Dubroca's avatar Sabrina Dubroca Committed by Greg Kroah-Hartman

ipv6: avoid overflow of offset in ip6_find_1stfragopt


[ Upstream commit 6399f1fa ]

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: default avatarSabrina Dubroca <sd@queasysnail.net>
Acked-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e9b2f461
...@@ -78,7 +78,7 @@ EXPORT_SYMBOL(ipv6_select_ident); ...@@ -78,7 +78,7 @@ EXPORT_SYMBOL(ipv6_select_ident);
int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
{ {
u16 offset = sizeof(struct ipv6hdr); unsigned int offset = sizeof(struct ipv6hdr);
unsigned int packet_len = skb_tail_pointer(skb) - unsigned int packet_len = skb_tail_pointer(skb) -
skb_network_header(skb); skb_network_header(skb);
int found_rhdr = 0; int found_rhdr = 0;
...@@ -86,6 +86,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) ...@@ -86,6 +86,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
while (offset <= packet_len) { while (offset <= packet_len) {
struct ipv6_opt_hdr *exthdr; struct ipv6_opt_hdr *exthdr;
unsigned int len;
switch (**nexthdr) { switch (**nexthdr) {
...@@ -111,7 +112,10 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) ...@@ -111,7 +112,10 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) + exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
offset); offset);
offset += ipv6_optlen(exthdr); len = ipv6_optlen(exthdr);
if (len + offset >= IPV6_MAXPLEN)
return -EINVAL;
offset += len;
*nexthdr = &exthdr->nexthdr; *nexthdr = &exthdr->nexthdr;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment