mirror of
https://github.com/apache/nuttx.git
synced 2026-05-29 04:19:37 +08:00
net/poll: fix race condition if connect free before poll teardown
Net poll teardown is not protected by net lock, if the conn is released before teardown, the assertion failure will be triggered during free dev callback, this patch will add the net lock around net poll teardown to fix race condition nuttx/libs/libc/assert/lib_assert.c:36 nuttx/net/devif/devif_callback.c:85 nuttx/net/tcp/tcp_netpoll.c:405 nuttx/fs/vfs/fs_poll.c:244 nuttx/fs/vfs/fs_poll.c:500 Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
+23
-15
@@ -198,25 +198,26 @@ static uint16_t tcp_poll_eventhandler(FAR struct net_driver_s *dev,
|
||||
|
||||
int tcp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds)
|
||||
{
|
||||
FAR struct tcp_conn_s *conn = psock->s_conn;
|
||||
FAR struct tcp_conn_s *conn;
|
||||
FAR struct tcp_poll_s *info;
|
||||
FAR struct devif_callback_s *cb;
|
||||
bool nonblock_conn;
|
||||
int ret = OK;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
if (!conn || !fds)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Some of the following must be atomic */
|
||||
/* Some of the following must be atomic */
|
||||
|
||||
net_lock();
|
||||
|
||||
conn = psock->s_conn;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
if (!conn || !fds)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* Non-blocking connection ? */
|
||||
|
||||
nonblock_conn = (conn->tcpstateflags == TCP_SYN_SENT &&
|
||||
@@ -382,22 +383,27 @@ errout_with_lock:
|
||||
|
||||
int tcp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds)
|
||||
{
|
||||
FAR struct tcp_conn_s *conn = psock->s_conn;
|
||||
FAR struct tcp_conn_s *conn;
|
||||
FAR struct tcp_poll_s *info;
|
||||
|
||||
/* Some of the following must be atomic */
|
||||
|
||||
net_lock();
|
||||
|
||||
conn = psock->s_conn;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
if (!conn || !fds->priv)
|
||||
{
|
||||
net_unlock();
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Recover the socket descriptor poll state info from the poll structure */
|
||||
|
||||
info = (FAR struct tcp_poll_s *)fds->priv;
|
||||
DEBUGASSERT(info != NULL && info->fds != NULL && info->cb != NULL);
|
||||
DEBUGASSERT(info->fds != NULL && info->cb != NULL);
|
||||
if (info != NULL)
|
||||
{
|
||||
/* Release the callback */
|
||||
@@ -413,5 +419,7 @@ int tcp_pollteardown(FAR struct socket *psock, FAR struct pollfd *fds)
|
||||
info->conn = NULL;
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user