summaryrefslogtreecommitdiffstats
path: root/linux-user/syscall.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-02-21 11:47:28 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-02-21 11:47:28 +0000
commit9bd9d5e3573ea0465b8eb5700e867674054d27f3 (patch)
treebf6a3d41697b14986a0b690d9ad0aec868e5f236 /linux-user/syscall.c
parent774d566cdbebb916af9760dac629aa7c1adf9d3d (diff)
parent69d4c703a549f0630793a67b16a8fc6bc14c8654 (diff)
downloadhqemu-9bd9d5e3573ea0465b8eb5700e867674054d27f3.zip
hqemu-9bd9d5e3573ea0465b8eb5700e867674054d27f3.tar.gz
Merge remote-tracking branch 'remotes/riku/linux-user-for-upstream' into staging
* remotes/riku/linux-user-for-upstream: linux-user: Fix error handling in target_to_host_semarray() linux-user: Implement BLKPG ioctl linux-user: Fix error handling in lock_iovec() linux-user/signal.c: Don't pass sigaction uninitialised sa_flags linux-user/elfload.c: Avoid calling g_free() on uninitialized data linux-user: sync syscall numbers upto 3.13 Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r--linux-user/syscall.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f370087..1407b7a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -107,6 +107,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
#include <linux/reboot.h>
#include <linux/route.h>
#include <linux/filter.h>
+#include <linux/blkpg.h>
#include "linux_loop.h"
#include "cpu-uname.h"
@@ -1707,6 +1708,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
struct iovec *vec;
abi_ulong total_len, max_len;
int i;
+ int err = 0;
if (count == 0) {
errno = 0;
@@ -1726,7 +1728,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
target_vec = lock_user(VERIFY_READ, target_addr,
count * sizeof(struct target_iovec), 1);
if (target_vec == NULL) {
- errno = EFAULT;
+ err = EFAULT;
goto fail2;
}
@@ -1740,7 +1742,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
abi_long len = tswapal(target_vec[i].iov_len);
if (len < 0) {
- errno = EINVAL;
+ err = EINVAL;
goto fail;
} else if (len == 0) {
/* Zero length pointer is ignored. */
@@ -1748,7 +1750,7 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
} else {
vec[i].iov_base = lock_user(type, base, len, copy);
if (!vec[i].iov_base) {
- errno = EFAULT;
+ err = EFAULT;
goto fail;
}
if (len > max_len - total_len) {
@@ -1763,9 +1765,10 @@ static struct iovec *lock_iovec(int type, abi_ulong target_addr,
return vec;
fail:
- free(vec);
- fail2:
unlock_user(target_vec, target_addr, 0);
+ fail2:
+ free(vec);
+ errno = err;
return NULL;
}
@@ -2427,10 +2430,15 @@ static inline abi_long target_to_host_semarray(int semid, unsigned short **host_
nsems = semid_ds.sem_nsems;
*host_array = malloc(nsems*sizeof(unsigned short));
+ if (!*host_array) {
+ return -TARGET_ENOMEM;
+ }
array = lock_user(VERIFY_READ, target_addr,
nsems*sizeof(unsigned short), 1);
- if (!array)
+ if (!array) {
+ free(*host_array);
return -TARGET_EFAULT;
+ }
for(i=0; i<nsems; i++) {
__get_user((*host_array)[i], &array[i]);
OpenPOWER on IntegriCloud