Merge branch 'tcp-options-oob-fixes'

Maxim Mikityanskiy says:

====================
Fix out of bounds when parsing TCP options

This series fixes out-of-bounds access in various places in the kernel
where parsing of TCP options takes place. Fortunately, many more
occurrences don't have this bug.

v2 changes:

synproxy: Added an early return when length < 0 to avoid calling
skb_header_pointer with negative length.

sch_cake: Added doff validation to avoid parsing garbage.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2021-06-10 14:26:18 -07:00
commit 0280f429dc
3 changed files with 12 additions and 1 deletions

View File

@ -356,6 +356,8 @@ void mptcp_get_options(const struct sk_buff *skb,
length--;
continue;
default:
if (length < 2)
return;
opsize = *ptr++;
if (opsize < 2) /* "silly options" */
return;

View File

@ -31,6 +31,9 @@ synproxy_parse_options(const struct sk_buff *skb, unsigned int doff,
int length = (th->doff * 4) - sizeof(*th);
u8 buf[40], *ptr;
if (unlikely(length < 0))
return false;
ptr = skb_header_pointer(skb, doff + sizeof(*th), length, buf);
if (ptr == NULL)
return false;
@ -47,6 +50,8 @@ synproxy_parse_options(const struct sk_buff *skb, unsigned int doff,
length--;
continue;
default:
if (length < 2)
return true;
opsize = *ptr++;
if (opsize < 2)
return true;

View File

@ -943,7 +943,7 @@ static struct tcphdr *cake_get_tcphdr(const struct sk_buff *skb,
}
tcph = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
if (!tcph)
if (!tcph || tcph->doff < 5)
return NULL;
return skb_header_pointer(skb, offset,
@ -967,6 +967,8 @@ static const void *cake_get_tcpopt(const struct tcphdr *tcph,
length--;
continue;
}
if (length < 2)
break;
opsize = *ptr++;
if (opsize < 2 || opsize > length)
break;
@ -1104,6 +1106,8 @@ static bool cake_tcph_may_drop(const struct tcphdr *tcph,
length--;
continue;
}
if (length < 2)
break;
opsize = *ptr++;
if (opsize < 2 || opsize > length)
break;