summary refs log tree commit diff stats
path: root/linux-user/syscall.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2008-02-04 22:26:57 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2008-02-04 22:26:57 +0000
commit41df841110c6102ee20faae9a172e69a5d4a7f2d (patch)
treebe3a3a09856bf8b32238e907c5bc582bf575993b /linux-user/syscall.c
parent3fe43da73708f0597f4c34263fa697fe82d95e9e (diff)
downloadfocaccia-qemu-41df841110c6102ee20faae9a172e69a5d4a7f2d.tar.gz
focaccia-qemu-41df841110c6102ee20faae9a172e69a5d4a7f2d.zip
lock_iovec() fix
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3967 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r--linux-user/syscall.c17
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);
         }