[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