aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilip Bozuta <Filip.Bozuta@syrmia.com>2020-07-24 20:16:51 +0200
committerLaurent Vivier <laurent@vivier.eu>2020-07-27 22:04:07 +0200
commit4d213001b356c4a24c05afbc72f4860088900627 (patch)
treef44c562bdb7470780bd5947e4969417d3dd6e33d
parentc9f8066697e0d3e77b97f6df423e9d6540b693be (diff)
downloadqemu-4d213001b356c4a24c05afbc72f4860088900627.zip
qemu-4d213001b356c4a24c05afbc72f4860088900627.tar.gz
qemu-4d213001b356c4a24c05afbc72f4860088900627.tar.bz2
linux-user: Fix syscall rt_sigtimedwait() implementation
Implementation of 'rt_sigtimedwait()' in 'syscall.c' uses the function 'target_to_host_timespec()' to transfer the value of 'struct timespec' from target to host. However, the implementation doesn't check whether this conversion succeeds and thus can cause an unaproppriate error instead of the 'EFAULT (Bad address)' which is supposed to be set if the conversion from target to host fails. This was confirmed with the LTP test for rt_sigtimedwait: "/testcases/kernel/syscalls/rt_sigtimedwait/rt_sigtimedwait01.c" which causes an unapropriate error in test case "test_bad_adress3" which is run with a bad adress for the 'struct timespec' argument: FAIL: test_bad_address3 (349): Unexpected failure: EAGAIN/EWOULDBLOCK (11) The test fails with an unexptected errno 'EAGAIN/EWOULDBLOCK' instead of the expected EFAULT. After the changes from this patch, the test case is executed successfully along with the other LTP test cases for 'rt_sigtimedwait()': PASS: test_bad_address3 (349): Test passed Signed-off-by: Filip Bozuta <Filip.Bozuta@syrmia.com> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20200724181651.167819-1-Filip.Bozuta@syrmia.com> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
-rw-r--r--linux-user/syscall.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f5c4f6b..c1ebf7b 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8868,7 +8868,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
unlock_user(p, arg1, 0);
if (arg3) {
puts = &uts;
- target_to_host_timespec(puts, arg3);
+ if (target_to_host_timespec(puts, arg3)) {
+ return -TARGET_EFAULT;
+ }
} else {
puts = NULL;
}