From 781d29a3372ec1f3de97ffc1860f83d4ad1b1f1b Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 14 Feb 2021 10:38:22 +0100 Subject: [PATCH] Kernel+Userland: Give sys$recvfd() an options argument for O_CLOEXEC @bugaevc pointed out that we shouldn't be setting this flag in userspace, and he's right of course. --- Kernel/Process.h | 2 +- Kernel/Syscalls/sendfd.cpp | 8 ++++++-- Userland/DevTools/UserspaceEmulator/Emulator.cpp | 6 +++--- Userland/DevTools/UserspaceEmulator/Emulator.h | 2 +- Userland/Libraries/LibC/sys/socket.cpp | 4 ++-- Userland/Libraries/LibC/sys/socket.h | 2 +- Userland/Libraries/LibIPC/Decoder.cpp | 6 +----- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Kernel/Process.h b/Kernel/Process.h index 06339be322..2b75d4e5eb 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -347,7 +347,7 @@ public: int sys$get_stack_bounds(FlatPtr* stack_base, size_t* stack_size); int sys$ptrace(Userspace); int sys$sendfd(int sockfd, int fd); - int sys$recvfd(int sockfd); + int sys$recvfd(int sockfd, int options); long sys$sysconf(int name); int sys$disown(ProcessID); void* sys$allocate_tls(size_t); diff --git a/Kernel/Syscalls/sendfd.cpp b/Kernel/Syscalls/sendfd.cpp index 0f420e3911..66f6b4d654 100644 --- a/Kernel/Syscalls/sendfd.cpp +++ b/Kernel/Syscalls/sendfd.cpp @@ -52,7 +52,7 @@ int Process::sys$sendfd(int sockfd, int fd) return local_socket.sendfd(*socket_description, *passing_descriptor); } -int Process::sys$recvfd(int sockfd) +int Process::sys$recvfd(int sockfd, int options) { REQUIRE_PROMISE(recvfd); auto socket_description = file_description(sockfd); @@ -74,7 +74,11 @@ int Process::sys$recvfd(int sockfd) if (received_descriptor_or_error.is_error()) return received_descriptor_or_error.error(); - m_fds[new_fd].set(*received_descriptor_or_error.value(), 0); + u32 fd_flags = 0; + if (options & O_CLOEXEC) + fd_flags |= FD_CLOEXEC; + + m_fds[new_fd].set(*received_descriptor_or_error.value(), fd_flags); return new_fd; } diff --git a/Userland/DevTools/UserspaceEmulator/Emulator.cpp b/Userland/DevTools/UserspaceEmulator/Emulator.cpp index 59e4730bad..7a40897f92 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator.cpp +++ b/Userland/DevTools/UserspaceEmulator/Emulator.cpp @@ -456,7 +456,7 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3) case SC_sendfd: return virt$sendfd(arg1, arg2); case SC_recvfd: - return virt$recvfd(arg1); + return virt$recvfd(arg1, arg2); case SC_open: return virt$open(arg1); case SC_pipe: @@ -563,9 +563,9 @@ int Emulator::virt$sendfd(int socket, int fd) return syscall(SC_sendfd, socket, fd); } -int Emulator::virt$recvfd(int socket) +int Emulator::virt$recvfd(int socket, int options) { - return syscall(SC_recvfd, socket); + return syscall(SC_recvfd, socket, options); } int Emulator::virt$profiling_enable(pid_t pid) diff --git a/Userland/DevTools/UserspaceEmulator/Emulator.h b/Userland/DevTools/UserspaceEmulator/Emulator.h index caaf32e391..961b9fcc89 100644 --- a/Userland/DevTools/UserspaceEmulator/Emulator.h +++ b/Userland/DevTools/UserspaceEmulator/Emulator.h @@ -171,7 +171,7 @@ private: int virt$ftruncate(int fd, off_t); mode_t virt$umask(mode_t); int virt$anon_create(size_t, int); - int virt$recvfd(int); + int virt$recvfd(int, int); int virt$sendfd(int, int); int virt$msyscall(FlatPtr); diff --git a/Userland/Libraries/LibC/sys/socket.cpp b/Userland/Libraries/LibC/sys/socket.cpp index a545e00021..20bd144a4f 100644 --- a/Userland/Libraries/LibC/sys/socket.cpp +++ b/Userland/Libraries/LibC/sys/socket.cpp @@ -151,9 +151,9 @@ int sendfd(int sockfd, int fd) __RETURN_WITH_ERRNO(rc, rc, -1); } -int recvfd(int sockfd) +int recvfd(int sockfd, int options) { - int rc = syscall(SC_recvfd, sockfd); + int rc = syscall(SC_recvfd, sockfd, options); __RETURN_WITH_ERRNO(rc, rc, -1); } } diff --git a/Userland/Libraries/LibC/sys/socket.h b/Userland/Libraries/LibC/sys/socket.h index c5a5943041..c73b2ed6c3 100644 --- a/Userland/Libraries/LibC/sys/socket.h +++ b/Userland/Libraries/LibC/sys/socket.h @@ -152,7 +152,7 @@ int setsockopt(int sockfd, int level, int option, const void*, socklen_t); int getsockname(int sockfd, struct sockaddr*, socklen_t*); int getpeername(int sockfd, struct sockaddr*, socklen_t*); int sendfd(int sockfd, int fd); -int recvfd(int sockfd); +int recvfd(int sockfd, int options); // These three are non-POSIX, but common: #define CMSG_ALIGN(x) (((x) + sizeof(void*) - 1) & ~(sizeof(void*) - 1)) diff --git a/Userland/Libraries/LibIPC/Decoder.cpp b/Userland/Libraries/LibIPC/Decoder.cpp index ccf07e6f58..0eef0a005a 100644 --- a/Userland/Libraries/LibIPC/Decoder.cpp +++ b/Userland/Libraries/LibIPC/Decoder.cpp @@ -171,15 +171,11 @@ bool Decoder::decode(Dictionary& dictionary) bool Decoder::decode([[maybe_unused]] File& file) { #ifdef __serenity__ - int fd = recvfd(m_sockfd); + int fd = recvfd(m_sockfd, O_CLOEXEC); if (fd < 0) { dbgln("recvfd: {}", strerror(errno)); return false; } - if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) { - dbgln("fcntl(F_SETFD, FD_CLOEXEC): {}", strerror(errno)); - return false; - } file = File(fd, File::ConstructWithReceivedFileDescriptor); return true; #else