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.
This commit is contained in:
Brian Gianforcaro 2021-07-28 01:49:04 -07:00 committed by Andreas Kling
parent 4b2651ddab
commit ddc950ce42
2 changed files with 12 additions and 10 deletions

View file

@ -15,8 +15,8 @@ namespace Kernel {
class FileDescription;
struct SocketPair {
NonnullRefPtr<FileDescription> description0;
NonnullRefPtr<FileDescription> description1;
NonnullRefPtr<FileDescription> description2;
};
class LocalSocket final : public Socket {

View file

@ -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;