qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 3/4] linux-user: Fix error handling in lock_iovec()


From: Peter Maydell
Subject: [Qemu-devel] [PATCH 3/4] linux-user: Fix error handling in lock_iovec()
Date: Mon, 17 Feb 2014 18:55:33 +0000

In lock_iovec() if lock_user() failed we were doing an unlock_user
but not a free(vec), which is the wrong way round. We were also
assuming that free() and unlock_user() don't touch errno, which
is not guaranteed. Fix both these problems.

Signed-off-by: Peter Maydell <address@hidden>
---
 linux-user/syscall.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f370087..bb3e4b1 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1707,6 +1707,7 @@ static struct iovec *lock_iovec(int type, abi_ulong 
target_addr,
     struct iovec *vec;
     abi_ulong total_len, max_len;
     int i;
+    int err = 0;
 
     if (count == 0) {
         errno = 0;
@@ -1726,7 +1727,7 @@ static struct iovec *lock_iovec(int type, abi_ulong 
target_addr,
     target_vec = lock_user(VERIFY_READ, target_addr,
                            count * sizeof(struct target_iovec), 1);
     if (target_vec == NULL) {
-        errno = EFAULT;
+        err = EFAULT;
         goto fail2;
     }
 
@@ -1740,7 +1741,7 @@ static struct iovec *lock_iovec(int type, abi_ulong 
target_addr,
         abi_long len = tswapal(target_vec[i].iov_len);
 
         if (len < 0) {
-            errno = EINVAL;
+            err = EINVAL;
             goto fail;
         } else if (len == 0) {
             /* Zero length pointer is ignored.  */
@@ -1748,7 +1749,7 @@ static struct iovec *lock_iovec(int type, abi_ulong 
target_addr,
         } else {
             vec[i].iov_base = lock_user(type, base, len, copy);
             if (!vec[i].iov_base) {
-                errno = EFAULT;
+                err = EFAULT;
                 goto fail;
             }
             if (len > max_len - total_len) {
@@ -1763,9 +1764,10 @@ static struct iovec *lock_iovec(int type, abi_ulong 
target_addr,
     return vec;
 
  fail:
-    free(vec);
- fail2:
     unlock_user(target_vec, target_addr, 0);
+ fail2:
+    free(vec);
+    errno = err;
     return NULL;
 }
 
-- 
1.8.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]