From 506e4bee7bb1da3a35d8f4ce877549a84b8c5f7b Mon Sep 17 00:00:00 2001 From: Irek Fakhrutdinov Date: Sun, 15 Mar 2020 11:12:42 +0100 Subject: [PATCH] zos: add checks to ensure behavior of epoll_wait PR-URL: https://github.com/libuv/libuv/pull/2013 Reviewed-By: Ben Noordhuis Reviewed-By: Richard Lau Signed-off-by: Irek Fakhrutdinov --- src/unix/os390-syscalls.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/unix/os390-syscalls.c b/src/unix/os390-syscalls.c index e8f90363..f7763f04 100644 --- a/src/unix/os390-syscalls.c +++ b/src/unix/os390-syscalls.c @@ -278,6 +278,8 @@ int epoll_ctl(uv__os390_epoll* lst, return 0; } +#define EP_MAX_PFDS (ULONG_MAX / sizeof(struct pollfd)) +#define EP_MAX_EVENTS (INT_MAX / sizeof(struct epoll_event)) int epoll_wait(uv__os390_epoll* lst, struct epoll_event* events, int maxevents, int timeout) { @@ -289,12 +291,32 @@ int epoll_wait(uv__os390_epoll* lst, struct epoll_event* events, struct pollfd msg_fd; int i; - _SET_FDS_MSGS(size, 1, lst->size - 1); + if (!lst || !lst->items || !events) { + errno = EFAULT; + return -1; + } + + if (lst->size > EP_MAX_PFDS) { + errno = EINVAL; + return -1; + } + + if (maxevents <= 0 || maxevents > EP_MAX_EVENTS) { + errno = EINVAL; + return -1; + } + + if (lst->size > 0) + _SET_FDS_MSGS(size, 1, lst->size - 1); + else + _SET_FDS_MSGS(size, 0, 0); pfds = lst->items; pollret = poll(pfds, size, timeout); if (pollret <= 0) return pollret; + assert(lst->size > 0); + pollret = _NFDS(pollret) + _NMSGS(pollret); reventcount = 0;