diff options
-rw-r--r-- | Kernel/Net/LocalSocket.h | 2 | ||||
-rw-r--r-- | Kernel/Syscalls/socket.cpp | 20 |
2 files changed, 12 insertions, 10 deletions
diff --git a/Kernel/Net/LocalSocket.h b/Kernel/Net/LocalSocket.h index 818608d8a5..1fc56c59a7 100644 --- a/Kernel/Net/LocalSocket.h +++ b/Kernel/Net/LocalSocket.h @@ -15,8 +15,8 @@ namespace Kernel { class FileDescription; struct SocketPair { + NonnullRefPtr<FileDescription> description0; NonnullRefPtr<FileDescription> description1; - NonnullRefPtr<FileDescription> description2; }; class LocalSocket final : public Socket { diff --git a/Kernel/Syscalls/socket.cpp b/Kernel/Syscalls/socket.cpp index 522881c224..e8d3a3bbda 100644 --- a/Kernel/Syscalls/socket.cpp +++ b/Kernel/Syscalls/socket.cpp @@ -412,21 +412,23 @@ KResultOr<FlatPtr> Process::sys$socketpair(Userspace<const Syscall::SC_socketpai return result.error(); auto pair = result.value(); - int fds[2]; + auto fd0_or_error = m_fds.allocate(); + if (fd0_or_error.is_error()) + return fd0_or_error.error(); auto fd1_or_error = m_fds.allocate(); if (fd1_or_error.is_error()) return fd1_or_error.error(); - fds[0] = fd1_or_error.value().fd; - setup_socket_fd(fds[0], pair.description1, params.type); - auto fd2_or_error = m_fds.allocate(); - if (fd2_or_error.is_error()) - return fd2_or_error.error(); - fds[1] = fd2_or_error.value().fd; - setup_socket_fd(fds[1], pair.description2, params.type); + int fds[2]; + fds[0] = fd0_or_error.value().fd; + fds[1] = fd1_or_error.value().fd; + setup_socket_fd(fds[0], pair.description0, params.type); + setup_socket_fd(fds[1], pair.description1, params.type); if (!copy_to_user(params.sv, fds, sizeof(fds))) { - // FIXME: This leaks both file descriptors + // Avoid leaking both file descriptors on error. + m_fds[fds[0]] = {}; + m_fds[fds[1]] = {}; return EFAULT; } return KSuccess; |