From 2ba7fae3bd688f5bb6cb08defc731d77e6bd943c Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 18 Jul 2016 15:35:59 +0100 Subject: linux-user: Check for bad event numbers in epoll_wait The kernel checks that the maxevents parameter to epoll_wait is non-negative and not larger than EP_MAX_EVENTS. Add this check to our implementation, so that: * we fail these cases EINVAL rather than EFAULT * we don't pass negative or overflowing values to the lock_user() size calculation Signed-off-by: Peter Maydell Signed-off-by: Riku Voipio --- linux-user/syscall.c | 5 +++++ linux-user/syscall_defs.h | 3 +++ 2 files changed, 8 insertions(+) (limited to 'linux-user') diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 21ae996dd1..eecccbb25c 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -11501,6 +11501,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, int maxevents = arg3; int timeout = arg4; + if (maxevents <= 0 || maxevents > TARGET_EP_MAX_EVENTS) { + ret = -TARGET_EINVAL; + break; + } + target_ep = lock_user(VERIFY_WRITE, arg2, maxevents * sizeof(struct target_epoll_event), 1); if (!target_ep) { diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index c0e5cb0010..5c19c5ca19 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -2585,6 +2585,9 @@ struct target_epoll_event { abi_uint events; target_epoll_data_t data; } TARGET_EPOLL_PACKED; + +#define TARGET_EP_MAX_EVENTS (INT_MAX / sizeof(struct target_epoll_event)) + #endif struct target_rlimit64 { uint64_t rlim_cur; -- cgit v1.2.3