[PATCH RFC POC 22/50] net: install SCM_RIGHTS descriptors when recvmsg() returns

From: Christian Brauner

Date: Tue Sep 15 2026 - 07:47:13 EST


scm_recv_one_fd() allocates a descriptor, writes the number into the
control message and installs the file right there, one descriptor at a
time. Everything that recvmsg() does after scm_detach_fds() can still
fail though. When it does the syscall returns -EFAULT while the received
descriptors are already in the table and the caller has no way to tell.

Reserve the descriptor with fd_prepare() and stage the file with
fd_stage(). The number is written to userspace as before, but the file
is only installed when recvmsg() returns success and dropped together
with the descriptor when it returns an error.

A control message that doesn't fit still gets only the descriptors it
can report and MSG_CTRUNC.

IORING_OP_RECVMSG reaches the same code from io-wq workers and the
SQPOLL thread. io_uring requests commit their reservations before the
completion is posted.

Signed-off-by: Christian Brauner (Amutable) <brauner@xxxxxxxxxx>
---
net/core/scm.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/net/core/scm.c b/net/core/scm.c
index f0d44ecdb11f..f05931eef54d 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -355,6 +355,7 @@ int scm_recv_one_fd(struct file *f, int __user *ufd, unsigned int flags,
bool notrunc)
{
int error;
+ const struct fd_slot *fd;

if (!ufd)
return -EFAULT;
@@ -363,16 +364,16 @@ int scm_recv_one_fd(struct file *f, int __user *ufd, unsigned int flags,
if (error)
return notrunc ? put_user(error, ufd) : error;

- FD_PREPARE(fdf, flags, get_file(f));
- if (fdf.err)
- return fdf.err;
+ fd = fd_prepare(flags);
+ if (IS_ERR(fd))
+ return PTR_ERR(fd);

- error = put_user(fd_prepare_fd(fdf), ufd);
+ error = put_user(fd_prepare_fd(fd), ufd);
if (error)
return error;

- __receive_sock(fd_prepare_file(fdf));
- return fd_publish(fdf);
+ __receive_sock(f);
+ return fd_stage(fd, get_file(f));
}

void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm, bool notrunc)

--
2.53.0