Skip to content

Commit

Permalink
ipv6: fix out-of-bound access in ip6_parse_tlv()
Browse files Browse the repository at this point in the history
[ Upstream commit 624085a ]

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: 1da177e ("Linux-2.6.12-rc2")
Fixes: c1412fc ("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>
  • Loading branch information
Eric Dumazet authored and gregkh committed Jul 14, 2021
1 parent 0f3ef67 commit 0da164a
Showing 1 changed file with 13 additions and 14 deletions.
27 changes: 13 additions & 14 deletions net/ipv6/exthdrs.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,18 +135,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.
Expand All @@ -163,12 +168,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;
Expand All @@ -188,7 +188,6 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
return false;

padlen = 0;
break;
}
off += optlen;
len -= optlen;
Expand Down

0 comments on commit 0da164a

Please sign in to comment.