| From foo@baz Thu Sep 14 23:20:08 PDT 2017 |
| From: Stefano Brivio <sbrivio@redhat.com> |
| Date: Fri, 18 Aug 2017 14:40:53 +0200 |
| Subject: ipv6: accept 64k - 1 packet length in ip6_find_1stfragopt() |
| |
| From: Stefano Brivio <sbrivio@redhat.com> |
| |
| |
| [ Upstream commit 3de33e1ba0506723ab25734e098cf280ecc34756 ] |
| |
| A packet length of exactly IPV6_MAXPLEN is allowed, we should |
| refuse parsing options only if the size is 64KiB or more. |
| |
| While at it, remove one extra variable and one assignment which |
| were also introduced by the commit that introduced the size |
| check. Checking the sum 'offset + len' and only later adding |
| 'len' to 'offset' doesn't provide any advantage over directly |
| summing to 'offset' and checking it. |
| |
| Fixes: 6399f1fae4ec ("ipv6: avoid overflow of offset in ip6_find_1stfragopt") |
| Signed-off-by: Stefano Brivio <sbrivio@redhat.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/ipv6/output_core.c | 6 ++---- |
| 1 file changed, 2 insertions(+), 4 deletions(-) |
| |
| --- a/net/ipv6/output_core.c |
| +++ b/net/ipv6/output_core.c |
| @@ -86,7 +86,6 @@ int ip6_find_1stfragopt(struct sk_buff * |
| |
| while (offset <= packet_len) { |
| struct ipv6_opt_hdr *exthdr; |
| - unsigned int len; |
| |
| switch (**nexthdr) { |
| |
| @@ -112,10 +111,9 @@ int ip6_find_1stfragopt(struct sk_buff * |
| |
| exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) + |
| offset); |
| - len = ipv6_optlen(exthdr); |
| - if (len + offset >= IPV6_MAXPLEN) |
| + offset += ipv6_optlen(exthdr); |
| + if (offset > IPV6_MAXPLEN) |
| return -EINVAL; |
| - offset += len; |
| *nexthdr = &exthdr->nexthdr; |
| } |
| |