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