@@ -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;
}
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 <mjt@tls.msk.ru> --- linux-user/syscall.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)