net/tcp: Add flag for tcp_close to avoid double free

Problem:
When tcp_close_work starts to run in LPWORK, if another event comes and
calls tcp_free before tcp_close_work takes net_lock, the tcp_free will
be called twice and cause double free.

Signed-off-by: Zhe Weng <wengzhe@xiaomi.com>
This commit is contained in:
Zhe Weng 2023-05-26 16:44:34 +08:00 committed by Alin Jerpelea
parent f4d409b3e5
commit 7d1b733202
3 changed files with 14 additions and 4 deletions

View File

@ -106,12 +106,13 @@
#define TCP_WSCALE 0x01U /* Window Scale option enabled */
#define TCP_SACK 0x02U /* Selective ACKs enabled */
#define TCP_CLOSE_ARRANGED 0x04U /* Connection is arranged to be freed */
#ifdef CONFIG_NET_TCP_CC_NEWRENO
/* The TCP flags for congestion control */
#define TCP_INFR 0x04U /* The flag in Fast Recovery */
#define TCP_INFT 0x08U /* The flag in Fast Transmitted */
#define TCP_INFR 0x08U /* The flag in Fast Recovery */
#define TCP_INFT 0x10U /* The flag in Fast Transmitted */
#endif

View File

@ -53,7 +53,8 @@ static void tcp_close_work(FAR void *param)
net_lock();
if (conn && conn->crefs == 0)
conn->flags &= ~TCP_CLOSE_ARRANGED;
if (conn->crefs == 0)
{
/* Stop the network monitor for all sockets */
@ -186,6 +187,7 @@ end_wait:
/* Free network resources */
conn->flags |= TCP_CLOSE_ARRANGED;
work_queue(LPWORK, &conn->clswork, tcp_close_work, conn, 0);
return flags;

View File

@ -842,7 +842,14 @@ void tcp_free(FAR struct tcp_conn_s *conn)
/* Cancel close work */
work_cancel(LPWORK, &conn->clswork);
if ((conn->flags & TCP_CLOSE_ARRANGED) &&
work_cancel(LPWORK, &conn->clswork) != OK)
{
/* Close work is already running, tcp_free will be called again. */
net_unlock();
return;
}
/* Cancel tcp timer */