Index: qemu/linux-user/syscall.c =================================================================== --- qemu.orig/linux-user/syscall.c 2007-09-16 16:03:46.000000000 -0400 +++ qemu/linux-user/syscall.c 2007-09-16 16:06:36.000000000 -0400 @@ -855,7 +855,7 @@ return ret; } -static void lock_iovec(struct iovec *vec, target_ulong target_addr, +static long copy_from_iovec(struct iovec *vec, target_ulong target_addr, int count, int copy) { struct target_iovec *target_vec; @@ -863,15 +863,18 @@ int i; target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1); + if( !access_ok(VERIFY_READ, target_vec, count * sizeof(struct target_iovec)) ) return -1; 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(base, vec[i].iov_len, copy); } unlock_user (target_vec, target_addr, 0); + + return 0; } -static void unlock_iovec(struct iovec *vec, target_ulong target_addr, +static long copy_to_iovec(struct iovec *vec, target_ulong target_addr, int count, int copy) { struct target_iovec *target_vec; @@ -879,11 +882,14 @@ int i; target_vec = lock_user(target_addr, count * sizeof(struct target_iovec), 1); + if( !access_ok(VERIFY_WRITE, target_vec, count * sizeof(struct target_iovec)) ) return -1; for(i = 0;i < count; i++) { base = tswapl(target_vec[i].iov_base); unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); } unlock_user (target_vec, target_addr, 0); + + return 0; } static long do_socket(int domain, int type, int protocol) @@ -959,7 +965,7 @@ count = tswapl(msgp->msg_iovlen); vec = alloca(count * sizeof(struct iovec)); target_vec = tswapl(msgp->msg_iov); - lock_iovec(vec, target_vec, count, send); + if( copy_from_iovec(vec, target_vec, count, send) ) return -EFAULT; msg.msg_iovlen = count; msg.msg_iov = vec; @@ -971,7 +977,7 @@ if (!is_error(ret)) host_to_target_cmsg(msgp, &msg); } - unlock_iovec(vec, target_vec, count, !send); + if( copy_to_iovec(vec, target_vec, count, !send) ) return -EFAULT; return ret; } @@ -3913,9 +3919,9 @@ struct iovec *vec; vec = alloca(count * sizeof(struct iovec)); - lock_iovec(vec, arg2, count, 0); + if( copy_from_iovec(vec, arg2, count, 0) ) return -EFAULT; ret = get_errno(readv(arg1, vec, count)); - unlock_iovec(vec, arg2, count, 1); + if( copy_to_iovec(vec, arg2, count, 1) ) return -EFAULT; } break; case TARGET_NR_writev: @@ -3924,9 +3930,9 @@ struct iovec *vec; vec = alloca(count * sizeof(struct iovec)); - lock_iovec(vec, arg2, count, 1); + if( copy_from_iovec(vec, arg2, count, 1) ) return -EFAULT; ret = get_errno(writev(arg1, vec, count)); - unlock_iovec(vec, arg2, count, 0); + if( copy_to_iovec(vec, arg2, count, 0) ) return -EFAULT; } break; case TARGET_NR_getsid: