diff options
author | Laurent Vivier <laurent@vivier.eu> | 2015-10-06 01:20:48 +0200 |
---|---|---|
committer | Riku Voipio <riku.voipio@linaro.org> | 2016-01-08 11:36:13 +0200 |
commit | 3e24bb3f1277ee25743f0a3274306080df80da2c (patch) | |
tree | a94ab664d729ab6e30ca6ef68b7add653061a3d7 /linux-user | |
parent | 928bed6a057cedd6110e634865e021a24029785a (diff) |
linux-user: in poll(), if nfds is 0, pfd can be NULL
This problem appears with yum in Fedora 20 / PPC64 container.
test case:
#include <stdio.h>
#include <poll.h>
int main(void)
{
int ret;
ret = poll(NULL, 0, 1000);
printf("%d\n", ret);
}
target test environment: Fedora 20 / PPC64
host test environment: Ubuntu 14.0.2 / x86_64
original test result: -1
13451 poll(0,0,1000,274886297496,268566664,268566648) = -1 errno=14 (Bad address)
patched test result: 0
13536 poll(0,0,1000,274886297496,268566664,268566648) = 0
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/syscall.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 8fa8e0ce14..c2169664d5 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8046,14 +8046,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, struct pollfd *pfd; unsigned int i; - target_pfd = lock_user(VERIFY_WRITE, arg1, sizeof(struct target_pollfd) * nfds, 1); - if (!target_pfd) - goto efault; + pfd = NULL; + target_pfd = NULL; + if (nfds) { + target_pfd = lock_user(VERIFY_WRITE, arg1, + sizeof(struct target_pollfd) * nfds, 1); + if (!target_pfd) { + goto efault; + } - pfd = alloca(sizeof(struct pollfd) * nfds); - for(i = 0; i < nfds; i++) { - pfd[i].fd = tswap32(target_pfd[i].fd); - pfd[i].events = tswap16(target_pfd[i].events); + pfd = alloca(sizeof(struct pollfd) * nfds); + for (i = 0; i < nfds; i++) { + pfd[i].fd = tswap32(target_pfd[i].fd); + pfd[i].events = tswap16(target_pfd[i].events); + } } # ifdef TARGET_NR_ppoll |