Skip to content

Commit

Permalink
linux-user: writev Partial Writes
Browse files Browse the repository at this point in the history
Although not technically not required by POSIX, the writev system call will
typically write out its buffers individually.  That is, if the first buffer
is written successfully, but the second buffer pointer is invalid, then
the first chuck will be written and its size is returned.

Signed-off-by: Tom Musta <[email protected]>
Reviewed-by: Peter Maydell <[email protected]>
Signed-off-by: Riku Voipio <[email protected]>
  • Loading branch information
Tom Musta authored and Riku Voipio committed Aug 22, 2014
1 parent 6f6a403 commit 29560a6
Showing 1 changed file with 14 additions and 2 deletions.
16 changes: 14 additions & 2 deletions linux-user/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -1803,6 +1803,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
abi_ulong total_len, max_len;
int i;
int err = 0;
bool bad_address = false;

if (count == 0) {
errno = 0;
Expand Down Expand Up @@ -1843,9 +1844,20 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
vec[i].iov_base = 0;
} else {
vec[i].iov_base = lock_user(type, base, len, copy);
/* If the first buffer pointer is bad, this is a fault. But
* subsequent bad buffers will result in a partial write; this
* is realized by filling the vector with null pointers and
* zero lengths. */
if (!vec[i].iov_base) {
err = EFAULT;
goto fail;
if (i == 0) {
err = EFAULT;
goto fail;
} else {
bad_address = true;
}
}
if (bad_address) {
len = 0;
}
if (len > max_len - total_len) {
len = max_len - total_len;
Expand Down

0 comments on commit 29560a6

Please sign in to comment.