Skip to content

Commit ddc950c

Browse files
bgianfoawesomekling
authored andcommitted
Kernel: Avoid file descriptor leak in Process::sys$socketpair on error
Previously it was possible to leak the file descriptor if we error out after allocating the first descriptor. Now we perform both fd allocations back to back so we can handle the potential error when processing the second fd allocation.
1 parent 4b2651d commit ddc950c

File tree

2 files changed

+12
-10
lines changed

2 files changed

+12
-10
lines changed

Kernel/Net/LocalSocket.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ namespace Kernel {
1515
class FileDescription;
1616

1717
struct SocketPair {
18+
NonnullRefPtr<FileDescription> description0;
1819
NonnullRefPtr<FileDescription> description1;
19-
NonnullRefPtr<FileDescription> description2;
2020
};
2121

2222
class LocalSocket final : public Socket {

Kernel/Syscalls/socket.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -412,21 +412,23 @@ KResultOr<FlatPtr> Process::sys$socketpair(Userspace<const Syscall::SC_socketpai
412412
return result.error();
413413
auto pair = result.value();
414414

415-
int fds[2];
415+
auto fd0_or_error = m_fds.allocate();
416+
if (fd0_or_error.is_error())
417+
return fd0_or_error.error();
416418
auto fd1_or_error = m_fds.allocate();
417419
if (fd1_or_error.is_error())
418420
return fd1_or_error.error();
419-
fds[0] = fd1_or_error.value().fd;
420-
setup_socket_fd(fds[0], pair.description1, params.type);
421421

422-
auto fd2_or_error = m_fds.allocate();
423-
if (fd2_or_error.is_error())
424-
return fd2_or_error.error();
425-
fds[1] = fd2_or_error.value().fd;
426-
setup_socket_fd(fds[1], pair.description2, params.type);
422+
int fds[2];
423+
fds[0] = fd0_or_error.value().fd;
424+
fds[1] = fd1_or_error.value().fd;
425+
setup_socket_fd(fds[0], pair.description0, params.type);
426+
setup_socket_fd(fds[1], pair.description1, params.type);
427427

428428
if (!copy_to_user(params.sv, fds, sizeof(fds))) {
429-
// FIXME: This leaks both file descriptors
429+
// Avoid leaking both file descriptors on error.
430+
m_fds[fds[0]] = {};
431+
m_fds[fds[1]] = {};
430432
return EFAULT;
431433
}
432434
return KSuccess;

0 commit comments

Comments
 (0)