From c101b576828471a84228eb01407efe2b370b0603 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Tue, 3 Apr 2018 23:50:39 +0200 Subject: [PATCH] kernel: Implement FD limit check for select/poll. The amount of FDs that can be selected/polled needs to be limited by the RLIMIT_NOFILES. --- src/system/kernel/wait_for_objects.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/system/kernel/wait_for_objects.cpp b/src/system/kernel/wait_for_objects.cpp index dbb6ffdb54..edc3b8a286 100644 --- a/src/system/kernel/wait_for_objects.cpp +++ b/src/system/kernel/wait_for_objects.cpp @@ -906,6 +906,15 @@ _kern_wait_for_objects(object_wait_info* infos, int numInfos, uint32 flags, // #pragma mark - User syscalls +static bool +check_max_fds(int numFDs) +{ + struct io_context *context = get_current_io_context(false); + MutexLocker(&context->io_mutex); + return numFDs <= context->table_size; +} + + ssize_t _user_select(int numFDs, fd_set *userReadSet, fd_set *userWriteSet, fd_set *userErrorSet, bigtime_t timeout, const sigset_t *userSigMask) @@ -917,7 +926,7 @@ _user_select(int numFDs, fd_set *userReadSet, fd_set *userWriteSet, syscall_restart_handle_timeout_pre(timeout); - if (numFDs < 0) + if (numFDs < 0 || !check_max_fds(numFDs)) return B_BAD_VALUE; if ((userReadSet != NULL && !IS_USER_ADDRESS(userReadSet)) @@ -1013,6 +1022,9 @@ _user_poll(struct pollfd *userfds, int numFDs, bigtime_t timeout) ? syscall_restart_handle_timeout_post(result, timeout) : result; } + if (!check_max_fds(numFDs)) + return B_BAD_VALUE; + // copy parameters if (userfds == NULL || !IS_USER_ADDRESS(userfds)) return B_BAD_ADDRESS;