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:
parent
0f9b3626c1
commit
bffd6576f9
1 changed files with 19 additions and 5 deletions
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue