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. Change-Id: I8ea25e46641eb1a03d1570c27551d0239674a3d7 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>
This commit is contained in:
parent
ef1d9a501e
commit
f2ef982024
|
@ -9,13 +9,14 @@
|
|||
|
||||
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 - skb->network_header;
|
||||
int found_rhdr = 0;
|
||||
*nexthdr = &ipv6_hdr(skb)->nexthdr;
|
||||
|
||||
while (offset <= packet_len) {
|
||||
struct ipv6_opt_hdr *exthdr;
|
||||
unsigned int len;
|
||||
|
||||
switch (**nexthdr) {
|
||||
|
||||
|
@ -41,7 +42,10 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
|
|||
|
||||
exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
|
||||
offset);
|
||||
offset += ipv6_optlen(exthdr);
|
||||
len = ipv6_optlen(exthdr);
|
||||
if (len + offset >= IPV6_MAXPLEN)
|
||||
return -EINVAL;
|
||||
offset += len;
|
||||
*nexthdr = &exthdr->nexthdr;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue