libc: handle invalid file descriptors in poll()

poll(2) needs to handle invalid file descriptors in the pollfd struct,
specifically -1 as it may be used to disable entries in the fds[] array.

Fix a possible nullptr dereference by checking the File_descriptor
pointer returned by find_by_libc_fd() for validity and skip processing
of any unresolved FDs, effectively implementing standard POSIX
semantics.

Fixes #5249
This commit is contained in:
Benjamin Lamowski 2024-06-14 09:02:32 +02:00 committed by Norman Feske
parent 9d42890fbf
commit e153f44ce8

View File

@ -54,7 +54,8 @@ static int poll_plugins(Plugin::Pollfd pollfds[], int nfds)
int plugin_nfds = 0;
for (int pollfd_index = 0; pollfd_index < nfds; pollfd_index++)
if (pollfds[pollfd_index].fdo->plugin == plugin)
if (pollfds[pollfd_index].fdo &&
pollfds[pollfd_index].fdo->plugin == plugin)
plugin_nfds++;
if (plugin_nfds == 0)
@ -71,7 +72,8 @@ static int poll_plugins(Plugin::Pollfd pollfds[], int nfds)
pollfd_index < nfds;
pollfd_index++) {
if (pollfds[pollfd_index].fdo->plugin == plugin) {
if (pollfds[pollfd_index].fdo &&
pollfds[pollfd_index].fdo->plugin == plugin) {
plugin_pollfds[plugin_pollfd_index] = pollfds[pollfd_index];
plugin_pollfd_index++;
}
@ -96,6 +98,12 @@ poll(struct pollfd pollfds[], nfds_t nfds, int timeout_ms)
/*
* Look up the file descriptor objects early-on to reduce repeated
* overhead.
*
* According to POSIX poll(2), a poolfd entry is ignored if 'fd' is
* negative, but 'revents' must be cleared (set to zero) nevertheless.
* Note, negative file descriptors result in a nullptr in fdo on calls to
* 'find_by_libc_fd()', which is checked against above and will result in
* the file descriptor being skipped.
*/
Plugin::Pollfd plugins_pollfds[nfds];