Commit d732dcb442ce810709f48d7a105b573efda118a2

Authored by balrog
1 parent a2f86d8e

Fix iovec for the case with invalid elements (Lauro Ramos Venancio).

We must call the writev even if an iovec element is invalid. For
example, if the second element is invalid, the linux process the first
one.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5562 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 7 additions and 13 deletions
linux-user/syscall.c
@@ -1064,7 +1064,7 @@ static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr, @@ -1064,7 +1064,7 @@ static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1064 { 1064 {
1065 struct target_iovec *target_vec; 1065 struct target_iovec *target_vec;
1066 abi_ulong base; 1066 abi_ulong base;
1067 - int i, j; 1067 + int i;
1068 1068
1069 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1); 1069 target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
1070 if (!target_vec) 1070 if (!target_vec)
@@ -1074,8 +1074,8 @@ static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr, @@ -1074,8 +1074,8 @@ static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1074 vec[i].iov_len = tswapl(target_vec[i].iov_len); 1074 vec[i].iov_len = tswapl(target_vec[i].iov_len);
1075 if (vec[i].iov_len != 0) { 1075 if (vec[i].iov_len != 0) {
1076 vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); 1076 vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
1077 - if (!vec[i].iov_base && vec[i].iov_len)  
1078 - goto fail; 1077 + /* Don't check lock_user return value. We must call writev even
  1078 + if a element has invalid base address. */
1079 } else { 1079 } else {
1080 /* zero length pointer is ignored */ 1080 /* zero length pointer is ignored */
1081 vec[i].iov_base = NULL; 1081 vec[i].iov_base = NULL;
@@ -1083,14 +1083,6 @@ static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr, @@ -1083,14 +1083,6 @@ static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
1083 } 1083 }
1084 unlock_user (target_vec, target_addr, 0); 1084 unlock_user (target_vec, target_addr, 0);
1085 return 0; 1085 return 0;
1086 - fail:  
1087 - /* failure - unwind locks */  
1088 - for (j = 0; j < i; j++) {  
1089 - base = tswapl(target_vec[j].iov_base);  
1090 - unlock_user(vec[j].iov_base, base, 0);  
1091 - }  
1092 - unlock_user (target_vec, target_addr, 0);  
1093 - return -TARGET_EFAULT;  
1094 } 1086 }
1095 1087
1096 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr, 1088 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
@@ -1104,8 +1096,10 @@ static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr, @@ -1104,8 +1096,10 @@ static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
1104 if (!target_vec) 1096 if (!target_vec)
1105 return -TARGET_EFAULT; 1097 return -TARGET_EFAULT;
1106 for(i = 0;i < count; i++) { 1098 for(i = 0;i < count; i++) {
1107 - base = tswapl(target_vec[i].iov_base);  
1108 - unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); 1099 + if (target_vec[i].iov_base) {
  1100 + base = tswapl(target_vec[i].iov_base);
  1101 + unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
  1102 + }
1109 } 1103 }
1110 unlock_user (target_vec, target_addr, 0); 1104 unlock_user (target_vec, target_addr, 0);
1111 1105