aboutsummaryrefslogtreecommitdiff
path: root/linux-user/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r--linux-user/syscall.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index d4398b9c56..5720195654 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1883,6 +1883,11 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
return vec;
fail:
+ while (--i >= 0) {
+ if (tswapal(target_vec[i].iov_len) > 0) {
+ unlock_user(vec[i].iov_base, tswapal(target_vec[i].iov_base), 0);
+ }
+ }
unlock_user(target_vec, target_addr, 0);
fail2:
free(vec);
@@ -1901,7 +1906,7 @@ static void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
if (target_vec) {
for (i = 0; i < count; i++) {
abi_ulong base = tswapal(target_vec[i].iov_base);
- abi_long len = tswapal(target_vec[i].iov_base);
+ abi_long len = tswapal(target_vec[i].iov_len);
if (len < 0) {
break;
}
@@ -3571,6 +3576,7 @@ static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
}
default:
ret = -TARGET_EINVAL;
+ unlock_user(argptr, guest_data, 0);
goto out;
}
unlock_user(argptr, guest_data, 0);
@@ -3690,6 +3696,7 @@ static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
break;
}
default:
+ unlock_user(argptr, guest_data, 0);
ret = -TARGET_EINVAL;
goto out;
}