Kernel: Avoid overrunning the user-specified buffers in select()

This commit is contained in:
Gunnar Beutner 2021-04-28 08:36:37 +02:00 committed by Andreas Kling
parent d9f7b29273
commit d9ee2c6a89

View file

@ -48,11 +48,16 @@ KResultOr<int> Process::sys$select(Userspace<const Syscall::SC_select_params*> u
});
fd_set fds_read, fds_write, fds_except;
if (params.readfds && !copy_from_user(&fds_read, params.readfds))
size_t bytes_used = ceil_div(params.nfds, 8);
if (bytes_used > sizeof(fds_read))
return EINVAL;
if (params.readfds && !copy_from_user(&fds_read, params.readfds, bytes_used))
return EFAULT;
if (params.writefds && !copy_from_user(&fds_write, params.writefds))
if (params.writefds && !copy_from_user(&fds_write, params.writefds, bytes_used))
return EFAULT;
if (params.exceptfds && !copy_from_user(&fds_except, params.exceptfds))
if (params.exceptfds && !copy_from_user(&fds_except, params.exceptfds, bytes_used))
return EFAULT;
Thread::SelectBlocker::FDVector fds_info;
@ -111,11 +116,11 @@ KResultOr<int> Process::sys$select(Userspace<const Syscall::SC_select_params*> u
}
}
if (params.readfds && !copy_to_user(params.readfds, &fds_read))
if (params.readfds && !copy_to_user(params.readfds, &fds_read, bytes_used))
return EFAULT;
if (params.writefds && !copy_to_user(params.writefds, &fds_write))
if (params.writefds && !copy_to_user(params.writefds, &fds_write, bytes_used))
return EFAULT;
if (params.exceptfds && !copy_to_user(params.exceptfds, &fds_except))
if (params.exceptfds && !copy_to_user(params.exceptfds, &fds_except, bytes_used))
return EFAULT;
return marked_fd_count;
}