in do_ppoll we've one place where unlock_user isn't done at all, while other places use 0 for the size of the area being unlocked instead of the actual size.
Instead of open-coding calls to unlock_user(), jump to the end of this function and do a single call to unlock there. Note: original code calls unlock_user() with target_pfd being NULL in one case (when nfds == 0). Move initializers to variable declarations, - I wondered a few times if target_pfd isn't being initialized at all for unlock_user. Signed-off-by: Michael Tokarev <[email protected]> --- linux-user/syscall.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 33bf84c205..eabdf50abc 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1487,14 +1487,12 @@ static abi_long do_pselect6(abi_long arg1, abi_long arg2, abi_long arg3, static abi_long do_ppoll(abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, bool ppoll, bool time64) { - struct target_pollfd *target_pfd; + struct target_pollfd *target_pfd = NULL; unsigned int nfds = arg2; - struct pollfd *pfd; + struct pollfd *pfd = NULL; unsigned int i; abi_long ret; - pfd = NULL; - target_pfd = NULL; if (nfds) { if (nfds > (INT_MAX / sizeof(struct target_pollfd))) { return -TARGET_EINVAL; @@ -1519,8 +1517,8 @@ static abi_long do_ppoll(abi_long arg1, abi_long arg2, abi_long arg3, if (time64 ? target_to_host_timespec64(timeout_ts, arg3) : target_to_host_timespec(timeout_ts, arg3)) { - unlock_user(target_pfd, arg1, 0); - return -TARGET_EFAULT; + ret = -TARGET_EFAULT; + goto out; } } else { timeout_ts = NULL; @@ -1529,8 +1527,7 @@ static abi_long do_ppoll(abi_long arg1, abi_long arg2, abi_long arg3, if (arg4) { ret = process_sigsuspend_mask(&set, arg4, arg5); if (ret != 0) { - unlock_user(target_pfd, arg1, 0); - return ret; + goto out; } } @@ -1544,7 +1541,8 @@ static abi_long do_ppoll(abi_long arg1, abi_long arg2, abi_long arg3, if (time64 ? host_to_target_timespec64(arg3, timeout_ts) : host_to_target_timespec(arg3, timeout_ts)) { - return -TARGET_EFAULT; + ret = -TARGET_EFAULT; + goto out; } } } else { @@ -1567,6 +1565,8 @@ static abi_long do_ppoll(abi_long arg1, abi_long arg2, abi_long arg3, target_pfd[i].revents = tswap16(pfd[i].revents); } } + +out: unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds); return ret; } -- 2.39.2
