diff mbox series

[v3,2/3] linux-user/syscall.c: do_ppoll: consolidate and fix the forgotten unlock_user

Message ID 20230914074337.149897-3-mjt@tls.msk.ru
State New
Headers show
Series linux-user/syscall.c: do_ppoll: eliminate large alloca | expand

Commit Message

Michael Tokarev Sept. 14, 2023, 7:43 a.m. UTC
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(-)
diff mbox series

Patch

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;
 }