net: tcp2: Fix handling single octet option at the EOL

This patch enables handling of a single octet of option-kind at the end
of the option list (EOL). Also, add functionality to drop a segment with
an invalid single octet option-kind at the EOL.

Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
This commit is contained in:
Ruslan Mstoi 2020-04-02 14:03:20 +03:00 committed by Jukka Rissanen
commit bffd6576f9

View file

@ -381,18 +381,24 @@ static bool tcp_options_check(void *buf, ssize_t len)
NET_DBG("len=%zd", len);
for ( ; len >= 2; options += opt_len, len -= opt_len) {
for ( ; len >= 1; options += opt_len, len -= opt_len) {
opt = options[0];
opt_len = (opt == TCPOPT_END || opt == TCPOPT_NOP) ?
1 : options[1];
NET_DBG("opt: %hu, opt_len: %hu", (u16_t)opt, (u16_t)opt_len);
if (opt == TCPOPT_END) {
break;
} else if (opt == TCPOPT_NOP) {
opt_len = 1;
continue;
} else {
if (len < 2) { /* Only END and NOP can have length 1 */
NET_ERR("Illegal option %d with length %d",
opt, len);
result = false;
break;
}
opt_len = options[1];
}
NET_DBG("opt: %hu, opt_len: %hu", (u16_t)opt, (u16_t)opt_len);
if (opt_len < 2 || opt_len > len) {
result = false;
@ -807,6 +813,7 @@ static void tcp_in(struct tcp *conn, struct net_pkt *pkt)
{
struct tcphdr *th = pkt ? th_get(pkt) : NULL;
u8_t next = 0, fl = th ? th->th_flags : 0;
size_t tcp_options_len = th ? (th->th_off - 5) * 4 : 0;
size_t len;
k_mutex_lock(&conn->lock, K_FOREVER);
@ -819,6 +826,13 @@ static void tcp_in(struct tcp *conn, struct net_pkt *pkt)
goto next_state;
}
if (tcp_options_len && !tcp_options_check((th + 1), tcp_options_len)) {
NET_DBG("DROP: Invalid TCP option list");
tcp_out(conn, RST);
conn_state(conn, TCP_CLOSED);
goto next_state;
}
if (FL(&fl, &, RST)) {
conn_state(conn, TCP_CLOSED);
}