diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-02-04 22:26:57 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-02-04 22:26:57 +0000 |
commit | 41df841110c6102ee20faae9a172e69a5d4a7f2d (patch) | |
tree | be3a3a09856bf8b32238e907c5bc582bf575993b | |
parent | 3fe43da73708f0597f4c34263fa697fe82d95e9e (diff) |
lock_iovec() fix
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3967 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | linux-user/syscall.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index d099e97daf..70aff84572 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1027,9 +1027,14 @@ static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr, for(i = 0;i < count; i++) { base = tswapl(target_vec[i].iov_base); vec[i].iov_len = tswapl(target_vec[i].iov_len); - vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); - if (!vec[i].iov_base) - goto fail; + if (vec[i].iov_len != 0) { + vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); + if (!vec[i].iov_base) + goto fail; + } else { + /* zero length pointer is ignored */ + vec[i].iov_base = NULL; + } } unlock_user (target_vec, target_addr, 0); return 0; @@ -4723,7 +4728,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, struct iovec *vec; vec = alloca(count * sizeof(struct iovec)); - lock_iovec(VERIFY_WRITE, vec, arg2, count, 0); + if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0) + goto efault; ret = get_errno(readv(arg1, vec, count)); unlock_iovec(vec, arg2, count, 1); } @@ -4734,7 +4740,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, struct iovec *vec; vec = alloca(count * sizeof(struct iovec)); - lock_iovec(VERIFY_READ, vec, arg2, count, 1); + if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) + goto efault; ret = get_errno(writev(arg1, vec, count)); unlock_iovec(vec, arg2, count, 0); } |