Commit 41df841110c6102ee20faae9a172e69a5d4a7f2d
1 parent
3fe43da7
lock_iovec() fix
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3967 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
12 additions
and
5 deletions
linux-user/syscall.c
| ... | ... | @@ -1027,9 +1027,14 @@ static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr, |
| 1027 | 1027 | for(i = 0;i < count; i++) { |
| 1028 | 1028 | base = tswapl(target_vec[i].iov_base); |
| 1029 | 1029 | vec[i].iov_len = tswapl(target_vec[i].iov_len); |
| 1030 | - vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); | |
| 1031 | - if (!vec[i].iov_base) | |
| 1032 | - goto fail; | |
| 1030 | + if (vec[i].iov_len != 0) { | |
| 1031 | + vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); | |
| 1032 | + if (!vec[i].iov_base) | |
| 1033 | + goto fail; | |
| 1034 | + } else { | |
| 1035 | + /* zero length pointer is ignored */ | |
| 1036 | + vec[i].iov_base = NULL; | |
| 1037 | + } | |
| 1033 | 1038 | } |
| 1034 | 1039 | unlock_user (target_vec, target_addr, 0); |
| 1035 | 1040 | return 0; |
| ... | ... | @@ -4723,7 +4728,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
| 4723 | 4728 | struct iovec *vec; |
| 4724 | 4729 | |
| 4725 | 4730 | vec = alloca(count * sizeof(struct iovec)); |
| 4726 | - lock_iovec(VERIFY_WRITE, vec, arg2, count, 0); | |
| 4731 | + if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0) | |
| 4732 | + goto efault; | |
| 4727 | 4733 | ret = get_errno(readv(arg1, vec, count)); |
| 4728 | 4734 | unlock_iovec(vec, arg2, count, 1); |
| 4729 | 4735 | } |
| ... | ... | @@ -4734,7 +4740,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
| 4734 | 4740 | struct iovec *vec; |
| 4735 | 4741 | |
| 4736 | 4742 | vec = alloca(count * sizeof(struct iovec)); |
| 4737 | - lock_iovec(VERIFY_READ, vec, arg2, count, 1); | |
| 4743 | + if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) | |
| 4744 | + goto efault; | |
| 4738 | 4745 | ret = get_errno(writev(arg1, vec, count)); |
| 4739 | 4746 | unlock_iovec(vec, arg2, count, 0); |
| 4740 | 4747 | } | ... | ... |