aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Leoshkevich <iii@linux.ibm.com>2023-02-24 01:39:06 +0100
committerMichael Tokarev <mjt@tls.msk.ru>2023-04-10 11:37:09 +0300
commitb6abbe6250a140d6f4b779f04c95e79a0f0aeffa (patch)
tree08417173559a07a96f7b0c9eb3421399912bbc4b
parentb57641e907acadd7593e0fec4ef52a21c9864aa7 (diff)
downloadqemu-b6abbe6250a140d6f4b779f04c95e79a0f0aeffa.zip
qemu-b6abbe6250a140d6f4b779f04c95e79a0f0aeffa.tar.gz
qemu-b6abbe6250a140d6f4b779f04c95e79a0f0aeffa.tar.bz2
linux-user: Fix unaligned memory access in prlimit64 syscall
target_rlimit64 contains uint64_t fields, so it's 8-byte aligned on some hosts, while some guests may align their respective type on a 4-byte boundary. This may lead to an unaligned access, which is an UB. Fix by defining the fields as abi_ullong. This makes the host alignment match that of the guest, and lets the compiler know that it should emit code that can deal with the guest alignment. While at it, also use __get_user() and __put_user() instead of tswap64(). Fixes: 163a05a8398b ("linux-user: Implement prlimit64 syscall") Reported-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20230224003907.263914-2-iii@linux.ibm.com> Signed-off-by: Laurent Vivier <laurent@vivier.eu> (cherry picked from commit 9c1da8b5ee7f6e80e6b683e7fb73df1029a7cbbe) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
-rw-r--r--linux-user/generic/target_resource.h4
-rw-r--r--linux-user/syscall.c8
2 files changed, 6 insertions, 6 deletions
diff --git a/linux-user/generic/target_resource.h b/linux-user/generic/target_resource.h
index 539d8c4..37d3eb0 100644
--- a/linux-user/generic/target_resource.h
+++ b/linux-user/generic/target_resource.h
@@ -12,8 +12,8 @@ struct target_rlimit {
};
struct target_rlimit64 {
- uint64_t rlim_cur;
- uint64_t rlim_max;
+ abi_ullong rlim_cur;
+ abi_ullong rlim_max;
};
#define TARGET_RLIM_INFINITY ((abi_ulong)-1)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 106d5ed..8f8f8cf 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -12888,8 +12888,8 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) {
return -TARGET_EFAULT;
}
- rnew.rlim_cur = tswap64(target_rnew->rlim_cur);
- rnew.rlim_max = tswap64(target_rnew->rlim_max);
+ __get_user(rnew.rlim_cur, &target_rnew->rlim_cur);
+ __get_user(rnew.rlim_max, &target_rnew->rlim_max);
unlock_user_struct(target_rnew, arg3, 0);
rnewp = &rnew;
}
@@ -12899,8 +12899,8 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) {
return -TARGET_EFAULT;
}
- target_rold->rlim_cur = tswap64(rold.rlim_cur);
- target_rold->rlim_max = tswap64(rold.rlim_max);
+ __put_user(rold.rlim_cur, &target_rold->rlim_cur);
+ __put_user(rold.rlim_max, &target_rold->rlim_max);
unlock_user_struct(target_rold, arg4, 1);
}
return ret;