ipv6: fix out-of-bound access in ip6_parse_tlv()
[ Upstream commit 624085a31c1ad6a80b1e53f686bf6ee92abbf6e8 ] First problem is that optlen is fetched without checking there is more than one byte to parse. Fix this by taking care of IPV6_TLV_PAD1 before fetching optlen (under appropriate sanity checks against len) Second problem is that IPV6_TLV_PADN checks of zero padding are performed before the check of remaining length. Fixes:1da177e4c3
("Linux-2.6.12-rc2") Fixes:c1412fce7e
("net/ipv6/exthdrs.c: Strict PadN option checking") Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Paolo Abeni <pabeni@redhat.com> Cc: Tom Herbert <tom@herbertland.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
3380206e5d
commit
48fa874498
@ -134,18 +134,23 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
|
||||
len -= 2;
|
||||
|
||||
while (len > 0) {
|
||||
int optlen = nh[off + 1] + 2;
|
||||
int i;
|
||||
int optlen, i;
|
||||
|
||||
switch (nh[off]) {
|
||||
case IPV6_TLV_PAD1:
|
||||
optlen = 1;
|
||||
if (nh[off] == IPV6_TLV_PAD1) {
|
||||
padlen++;
|
||||
if (padlen > 7)
|
||||
goto bad;
|
||||
break;
|
||||
off++;
|
||||
len--;
|
||||
continue;
|
||||
}
|
||||
if (len < 2)
|
||||
goto bad;
|
||||
optlen = nh[off + 1] + 2;
|
||||
if (optlen > len)
|
||||
goto bad;
|
||||
|
||||
case IPV6_TLV_PADN:
|
||||
if (nh[off] == IPV6_TLV_PADN) {
|
||||
/* RFC 2460 states that the purpose of PadN is
|
||||
* to align the containing header to multiples
|
||||
* of 8. 7 is therefore the highest valid value.
|
||||
@ -162,12 +167,7 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
|
||||
if (nh[off + i] != 0)
|
||||
goto bad;
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* Other TLV code so scan list */
|
||||
if (optlen > len)
|
||||
goto bad;
|
||||
|
||||
} else {
|
||||
tlv_count++;
|
||||
if (tlv_count > max_count)
|
||||
goto bad;
|
||||
@ -187,7 +187,6 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
|
||||
return false;
|
||||
|
||||
padlen = 0;
|
||||
break;
|
||||
}
|
||||
off += optlen;
|
||||
len -= optlen;
|
||||
|
Loading…
Reference in New Issue
Block a user