diff --git a/Kernel/Syscalls/select.cpp b/Kernel/Syscalls/select.cpp index 0df46b4390..175a07e650 100644 --- a/Kernel/Syscalls/select.cpp +++ b/Kernel/Syscalls/select.cpp @@ -48,11 +48,16 @@ KResultOr Process::sys$select(Userspace 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 Process::sys$select(Userspace 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; }