Skip to content

Commit 624085a

Browse files
edumazetdavem330
authored andcommitted
ipv6: fix out-of-bound access in ip6_parse_tlv()
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 <[email protected]> Cc: Paolo Abeni <[email protected]> Cc: Tom Herbert <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d9b6d26 commit 624085a

File tree

1 file changed

+13
-14
lines changed

1 file changed

+13
-14
lines changed

net/ipv6/exthdrs.c

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,23 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
135135
len -= 2;
136136

137137
while (len > 0) {
138-
int optlen = nh[off + 1] + 2;
139-
int i;
138+
int optlen, i;
140139

141-
switch (nh[off]) {
142-
case IPV6_TLV_PAD1:
143-
optlen = 1;
140+
if (nh[off] == IPV6_TLV_PAD1) {
144141
padlen++;
145142
if (padlen > 7)
146143
goto bad;
147-
break;
144+
off++;
145+
len--;
146+
continue;
147+
}
148+
if (len < 2)
149+
goto bad;
150+
optlen = nh[off + 1] + 2;
151+
if (optlen > len)
152+
goto bad;
148153

149-
case IPV6_TLV_PADN:
154+
if (nh[off] == IPV6_TLV_PADN) {
150155
/* RFC 2460 states that the purpose of PadN is
151156
* to align the containing header to multiples
152157
* of 8. 7 is therefore the highest valid value.
@@ -163,12 +168,7 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
163168
if (nh[off + i] != 0)
164169
goto bad;
165170
}
166-
break;
167-
168-
default: /* Other TLV code so scan list */
169-
if (optlen > len)
170-
goto bad;
171-
171+
} else {
172172
tlv_count++;
173173
if (tlv_count > max_count)
174174
goto bad;
@@ -188,7 +188,6 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
188188
return false;
189189

190190
padlen = 0;
191-
break;
192191
}
193192
off += optlen;
194193
len -= optlen;

0 commit comments

Comments
 (0)