Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from May 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions net/tcp/tcp.h
Expand Up @@ -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

Expand Down
4 changes: 3 additions & 1 deletion net/tcp/tcp_close.c
Expand Up @@ -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 */

Expand Down Expand Up @@ -186,6 +187,7 @@ static uint16_t tcp_close_eventhandler(FAR struct net_driver_s *dev,

/* Free network resources */

conn->flags |= TCP_CLOSE_ARRANGED;
work_queue(LPWORK, &conn->clswork, tcp_close_work, conn, 0);

return flags;
Expand Down
9 changes: 8 additions & 1 deletion net/tcp/tcp_conn.c
Expand Up @@ -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 */

Expand Down