Le 30/05/2019 à 18:00, Laurent Vivier a écrit : > Le 30/05/2019 à 17:25, Giuseppe Musacchio a écrit : >> The `event` parameter is ignored by the kernel if `op` is EPOLL_CTL_DEL, >> do the same and avoid returning EFAULT if garbage is passed instead of a >> valid pointer. >> >> Signed-off-by: Giuseppe Musacchio <thatle...@gmail.com> >> --- >> linux-user/syscall.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/linux-user/syscall.c b/linux-user/syscall.c >> index 5e29e675e9..32d463d58d 100644 >> --- a/linux-user/syscall.c >> +++ b/linux-user/syscall.c >> @@ -11329,7 +11329,7 @@ static abi_long do_syscall1(void *cpu_env, int >> num, abi_long arg1, >> { >> struct epoll_event ep; >> struct epoll_event *epp = 0; >> - if (arg4) { >> + if (arg2 != EPOLL_CTL_DEL && arg4) { >> struct target_epoll_event *target_ep; >> if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) { >> return -TARGET_EFAULT; > > Reviewed-by: Laurent Vivier <laur...@vivier.eu> >
in fact, the BUGS section of epoll_ctl(2) says: "In kernel versions before 2.6.9, the EPOLL_CTL_DEL operation required a non-null pointer in event, even though this argument is ignored. Since Linux 2.6.9, event can be specified as NULL when using EPOLL_CTL_DEL. Applications that need to be portable to kernels before 2.6.9 should specify a non-null pointer in event." So something like this would be more portable: @@ -11329,6 +11329,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, struct epoll_event ep; struct epoll_event *epp = 0; if (arg4) { + if (arg2 != EPOLL_CTL_DEL) { struct target_epoll_event *target_ep; if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) { return -TARGET_EFAULT; @@ -11340,6 +11341,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, */ ep.data.u64 = tswap64(target_ep->data.u64); unlock_user_struct(target_ep, arg4, 0); + } + /* + * before kernel 2.6.9, EPOLL_CTL_DEL operation required a + * non-null pointer, even though this argument is ignored. + * */ epp = &ep; } Thanks, Laurent