receive_fd() cannot defer to syscall exit as SECCOMP_IOCTL_NOTIF_ADDFD installs into the target task and hands the number to the supervisor and IORING_OP_FIXED_FD_INSTALL runs from an io_uring op. Open-code the get_unused_fd_flags() + fd_install() it did through FD_PREPARE(). Signed-off-by: Christian Brauner (Amutable) --- fs/file.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/fs/file.c b/fs/file.c index 2b041b45f225..1f06d0c846c2 100644 --- a/fs/file.c +++ b/fs/file.c @@ -1607,25 +1607,27 @@ int replace_fd(unsigned fd, struct file *file, unsigned flags) */ int receive_fd(struct file *file, int __user *ufd, unsigned int o_flags) { - int error; + int fd, error; error = security_file_receive(file); if (error) return error; - FD_PREPARE(fdf, o_flags, file); - if (fdf.err) - return fdf.err; - get_file(file); + fd = get_unused_fd_flags(o_flags); + if (fd < 0) + return fd; if (ufd) { - error = put_user(fd_prepare_fd(fdf), ufd); - if (error) + error = put_user(fd, ufd); + if (error) { + put_unused_fd(fd); return error; + } } - __receive_sock(fd_prepare_file(fdf)); - return fd_publish(fdf); + __receive_sock(file); + fd_install(fd, get_file(file)); + return fd; } EXPORT_SYMBOL_GPL(receive_fd); -- 2.53.0