aboutsummaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
authorFilip Bozuta <Filip.Bozuta@syrmia.com>2020-08-24 21:37:51 +0200
committerLaurent Vivier <laurent@vivier.eu>2020-08-27 12:29:50 +0200
commitdcbcf5cf1cddd0fa3e39fbea3b97e6cd0b5078f4 (patch)
tree5b1d56ca1f54db29744e18e092d54b16fcb63864 /linux-user
parentace3d65459a01bfd8c2c59ecabb5fd6839b2de54 (diff)
downloadqemu-dcbcf5cf1cddd0fa3e39fbea3b97e6cd0b5078f4.zip
qemu-dcbcf5cf1cddd0fa3e39fbea3b97e6cd0b5078f4.tar.gz
qemu-dcbcf5cf1cddd0fa3e39fbea3b97e6cd0b5078f4.tar.bz2
linux-user: Fix 'mq_timedsend()' and 'mq_timedreceive()'
Implementations of syscalls 'mq_timedsend()' and 'mq_timedreceive()' in 'syscall.c' use functions 'target_to_host_timespec()' and 'host_to_target_timespec()' to transfer the value of 'struct timespec' between target and host. However, the implementations don'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 modified LTP test suite where test cases with a bad adress for 'timespec' were added. This modified test suite can be found at: https://github.com/bozutaf/ltp Without the changes from this patch the bad adress testcase for 'mq_timedsend()' succeds unexpectedly, while the test returns errno 'ETIMEOUT' for 'mq_timedreceive()': mq_timedsend01.c:190: FAIL: mq_timedsend() returned 0, expected -1: SUCCESS (0) mq_timedreceive01.c:178: FAIL: mq_timedreceive() failed unexpectedly, expected EFAULT: ETIMEDOUT (110) After the changes from this patch, testcases for both syscalls fail with EFAULT as expected, which is the same test result that is received with native execution: mq_timedsend01.c:187: PASS: mq_timedsend() failed expectedly: EFAULT (14) mq_timedreceive01.c:180: PASS: mq_timedreceive() failed expectedly: EFAULT (14) (Patch with this new test case will be sent to LTP mailing list soon) Signed-off-by: Filip Bozuta <Filip.Bozuta@syrmia.com> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20200824193752.67950-2-Filip.Bozuta@syrmia.com> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/syscall.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 78e404c..fd13e72 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -12043,9 +12043,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
p = lock_user (VERIFY_READ, arg2, arg3, 1);
if (arg5 != 0) {
- target_to_host_timespec(&ts, arg5);
+ if (target_to_host_timespec(&ts, arg5)) {
+ return -TARGET_EFAULT;
+ }
ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, &ts));
- host_to_target_timespec(arg5, &ts);
+ if (!is_error(ret) && host_to_target_timespec(arg5, &ts)) {
+ return -TARGET_EFAULT;
+ }
} else {
ret = get_errno(safe_mq_timedsend(arg1, p, arg3, arg4, NULL));
}
@@ -12062,10 +12066,14 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
p = lock_user (VERIFY_READ, arg2, arg3, 1);
if (arg5 != 0) {
- target_to_host_timespec(&ts, arg5);
+ if (target_to_host_timespec(&ts, arg5)) {
+ return -TARGET_EFAULT;
+ }
ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
&prio, &ts));
- host_to_target_timespec(arg5, &ts);
+ if (!is_error(ret) && host_to_target_timespec(arg5, &ts)) {
+ return -TARGET_EFAULT;
+ }
} else {
ret = get_errno(safe_mq_timedreceive(arg1, p, arg3,
&prio, NULL));