This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit ad41d0e8732597da49523079c3b64257bbcbabd1
Author: zhangbo56 <[email protected]>
AuthorDate: Wed Jun 25 22:52:23 2025 +0800

    vsock: Fix accept shutdown race condition
    
    if server recive shutdown in vsock accept, it may not remove conn correctly
    
    Signed-off-by: zhangbo56 <[email protected]>
---
 net/vsock/vsock_sockif.c | 37 ++++++++++++++++++++++++++++++-------
 1 file changed, 30 insertions(+), 7 deletions(-)

diff --git a/net/vsock/vsock_sockif.c b/net/vsock/vsock_sockif.c
index a7506eaed81..0f4fd5f8844 100644
--- a/net/vsock/vsock_sockif.c
+++ b/net/vsock/vsock_sockif.c
@@ -392,42 +392,51 @@ static inline_function void vsock_poll_notify(FAR struct 
vsock_conn_s *conn,
 
 static void vsock_notify(FAR struct vsock_conn_s *conn, int type)
 {
+  pollevent_t eventset = 0;
+
   switch (type)
     {
       case VSOCK_NOTIFY_ERROR:
         vsock_post(&conn->rx_sem);
         vsock_post(&conn->tx_sem);
-        vsock_poll_notify(conn, POLLIN | POLLOUT);
+        eventset = POLLIN | POLLOUT;
         break;
       case VSOCK_NOTIFY_LISTEN:
         vsock_post(&conn->rx_sem);
-        vsock_poll_notify(conn, POLLIN);
+        eventset = POLLIN;
         break;
       case VSOCK_NOTIFY_SEND:
         vsock_post(&conn->tx_sem);
-        vsock_poll_notify(conn, POLLOUT);
+        eventset = POLLOUT;
         break;
       case VSOCK_NOTIFY_RECV:
         if (vsock_get_rx_size(conn) >= conn->rx_lowat)
           {
             vsock_post(&conn->rx_sem);
-            vsock_poll_notify(conn, POLLIN);
+            eventset = POLLIN;
           }
         break;
       case VSOCK_NOTIFY_SHUTDOWN:
         if (conn->shutdown & SHUT_RD)
           {
             vsock_post(&conn->rx_sem);
-            vsock_poll_notify(conn, POLLIN);
+            eventset |= POLLIN;
           }
 
         if (conn->shutdown & SHUT_WR)
           {
             vsock_post(&conn->tx_sem);
-            vsock_poll_notify(conn, POLLOUT);
+            eventset |= POLLOUT;
+          }
+
+        if (VSOCK_IS_SHUTDOWN(conn->shutdown))
+          {
+            eventset |= POLLHUP;
           }
         break;
     }
+
+  vsock_poll_notify(conn, eventset);
 }
 
 /****************************************************************************
@@ -1749,11 +1758,25 @@ static int vsock_accept(FAR struct socket *psock, FAR 
struct sockaddr *addr,
       FAR struct vsock_conn_s *conn = NULL;
 
       vsock_lock(server);
-      if (!list_is_empty(&server->child))
+      while (!list_is_empty(&server->child))
         {
           conn = list_first_entry(&server->child, struct vsock_conn_s,
                                   child);
           list_delete(&conn->child);
+
+          vsock_lock(conn);
+          if (VSOCK_IS_SHUTDOWN(conn->shutdown))
+            {
+              vsock_remove_conn(conn);
+              vsock_unlock(conn);
+              vsock_sub_ref(conn);
+              conn = NULL;
+            }
+          else
+            {
+              vsock_unlock(conn);
+              break;
+            }
         }
 
       vsock_unlock(server);

Reply via email to