net: tcp: Accept connections only in LISTENING state

Issue noticed with following scenario.

 1) TCP server is listening for connections but will handle
    only one connection at a time (e.g. echo-server sample)
 2) Client A connects, and the connection is accepted.
 3) Client B connects, instead of denying a connection,
    it is "auto" accepted (this is the actual bug) even
    if the application has not called accept().
 4) After the connection A is closed, the connection B
    gets accepted by application but now the closed
    connection A will cause confusion in the net-stack
 5) This confusion can cause memory leak or double free
    in the TCP core.

It is not easy to trigger this issue because it depends
on timing of the connections A & B.

Fixes: #18308

Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
This commit is contained in:
Ravi kumar Veeramally 2019-09-06 10:57:14 +03:00 committed by Jukka Rissanen
parent 8fa6dfbe5a
commit 1a6f4a6368
2 changed files with 17 additions and 0 deletions

View File

@ -2266,6 +2266,11 @@ NET_CONN_CB(tcp_syn_rcvd)
switch (net_tcp_get_state(tcp)) {
case NET_TCP_LISTEN:
if (net_context_get_state(context) != NET_CONTEXT_LISTENING) {
NET_DBG("Context %p is not listening", context);
return NET_DROP;
}
net_context_set_iface(context, net_pkt_iface(pkt));
break;
case NET_TCP_SYN_RCVD:
@ -2452,6 +2457,14 @@ NET_CONN_CB(tcp_syn_rcvd)
0,
context->user_data);
net_pkt_unref(pkt);
/* Set the context in CONNECTED state, so that it can not
* accept any new connections. If application is ready to
* accept the connection, zsock_accept_ctx() will set
* the state back to LISTENING.
*/
net_context_set_state(context, NET_CONTEXT_CONNECTED);
return NET_OK;
}

View File

@ -385,6 +385,10 @@ int zsock_accept_ctx(struct net_context *parent, struct sockaddr *addr,
return -1;
}
if (net_context_get_ip_proto(parent) == IPPROTO_TCP) {
net_context_set_state(parent, NET_CONTEXT_LISTENING);
}
struct net_context *ctx = k_fifo_get(&parent->accept_q, K_FOREVER);
#ifdef CONFIG_USERSPACE