Commit 0359338fd8cf for kernel
commit 0359338fd8cf1a2dc001d0cd69c331c17decee88
Author: Wenbo Sun <sunwenbo@cmss.chinamobile.com>
Date: Wed Nov 11 10:32:22 2026 +0800
af_unix: Inherit SO_INQ in unix_stream_connect()
When SO_INQ is enabled on a listening AF_UNIX SOCK_STREAM socket,
accepted sockets created by unix_stream_connect() do not inherit
u->recvmsg_inq from the listener, unlike TCP_INQ, AF_VSOCK SO_INQ,
and AF_UNIX SO_RIGHTS_NOTRUNC. As a result, recvmsg() on the
accepted socket never puts an SCM_INQ control message unless SO_INQ
is set again after accept().
Copy otheru->recvmsg_inq to newu->recvmsg_inq in
unix_stream_connect() using READ_ONCE() to pair with the lockless
WRITE_ONCE() in unix_setsockopt().
Found during LLM-assisted code review of unix_stream_connect() while
comparing option inheritance between SO_INQ and SO_RIGHTS_NOTRUNC.
Confirmed on UML (x86_64) by enabling SO_INQ on a listening AF_UNIX
SOCK_STREAM socket before listen() and accept(), sending data from a
connected client, and observing that recvmsg() on the accepted socket
returned no SCM_INQ control message.
Tested on UML (x86_64) against the reproducer, verifying that
recvmsg() on the accepted socket now returns the expected SCM_INQ
control message, and ran the tools/testing/selftests/net/af_unix/scm_inq
selftest (all 6 test cases passed).
Fixes: df30285b3670 ("af_unix: Introduce SO_INQ.")
Signed-off-by: Wenbo Sun <sunwenbo@cmss.chinamobile.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20261111023222.77227-1-sunwenbo@cmss.chinamobile.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 98fcfd7301f6..f847cf1fbeaf 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1750,6 +1750,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr_unsized *uad
newu = unix_sk(newsk);
otheru = unix_sk(other);
newu->listener = other;
+ newu->recvmsg_inq = READ_ONCE(otheru->recvmsg_inq);
newu->scm_rights_notrunc = READ_ONCE(otheru->scm_rights_notrunc);
RCU_INIT_POINTER(newsk->sk_wq, &newu->peer_wq);