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

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


The following commit(s) were added to refs/heads/master by this push:
     new f6109441323 net/local: Do not release the control files of a closed 
peer.
f6109441323 is described below

commit f6109441323de4509c2fc3f0bed2b9bb75198d8c
Author: Marco Casaroli <[email protected]>
AuthorDate: Fri Nov 6 08:26:03 2026 +0100

    net/local: Do not release the control files of a closed peer.
    
    sendmsg() with SCM_RIGHTS queues the files on the peer.  If the send then
    fails because the peer closed, local_free() of the peer already released
    them and cleared lc_peer.  local_freectl() then takes the sender as the
    peer, where lc_cfpcount is 0, and reads lc_cfps[65535].  The program never
    ends, and the prompt does not come back.
    
    Release the files only if the peer is the same as when they were queued,
    and stop when lc_cfpcount is 0, because the receiver can take them first.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 net/local/local_sendmsg.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/net/local/local_sendmsg.c b/net/local/local_sendmsg.c
index ba522adab15..0211ac642a4 100644
--- a/net/local/local_sendmsg.c
+++ b/net/local/local_sendmsg.c
@@ -68,7 +68,9 @@ static void local_freectl(FAR struct local_conn_s *conn, int 
count)
       peer = conn;
     }
 
-  while (count-- > 0)
+  /* The receiver can take the files first */
+
+  while (count-- > 0 && peer->lc_cfpcount > 0)
     {
       file_put(peer->lc_cfps[--peer->lc_cfpcount]);
       peer->lc_cfps[peer->lc_cfpcount] = NULL;
@@ -76,7 +78,8 @@ static void local_freectl(FAR struct local_conn_s *conn, int 
count)
 }
 
 static int local_sendctl(FAR struct local_conn_s *conn,
-                         FAR const struct msghdr *msg)
+                         FAR const struct msghdr *msg,
+                         FAR struct local_conn_s **speer)
 {
   FAR struct local_conn_s *peer;
   FAR struct file *filep;
@@ -87,6 +90,7 @@ static int local_sendctl(FAR struct local_conn_s *conn,
   int i = 0;
 
   local_lock();
+  *speer = conn->lc_peer;
   peer = conn->lc_peer;
   if (peer == NULL)
     {
@@ -463,6 +467,7 @@ ssize_t local_sendmsg(FAR struct socket *psock, FAR const 
struct msghdr *msg,
 
 #ifdef CONFIG_NET_LOCAL_SCM
   FAR struct local_conn_s *conn = psock->s_conn;
+  FAR struct local_conn_s *peer = NULL;
   int count = 0;
 
   if (msg->msg_control &&
@@ -486,7 +491,7 @@ ssize_t local_sendmsg(FAR struct socket *psock, FAR const 
struct msghdr *msg,
             }
         }
 
-      count = local_sendctl(conn, msg);
+      count = local_sendctl(conn, msg, &peer);
       if (count < 0)
         {
           return count;
@@ -498,8 +503,14 @@ ssize_t local_sendmsg(FAR struct socket *psock, FAR const 
struct msghdr *msg,
 
   if (ret < 0 && count > 0)
     {
+      /* A peer that closed during the send released the files itself */
+
       local_lock();
-      local_freectl(conn, count);
+      if (conn->lc_peer == peer)
+        {
+          local_freectl(conn, count);
+        }
+
       local_unlock();
     }
 #else

Reply via email to