From: riku.voipio@linaro.org
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>
Subject: [Qemu-devel] [PULL 06/16] linux-user: Check sigsetsize argument to syscalls
Date: Tue, 19 Jul 2016 15:54:04 +0300 [thread overview]
Message-ID: <c815701e8169d25ae6f84183f4b593b9335a9798.1468932683.git.riku.voipio@linaro.org> (raw)
In-Reply-To: <cover.1468932683.git.riku.voipio@linaro.org>
From: Peter Maydell <peter.maydell@linaro.org>
Many syscalls which take a sigset_t argument also take an argument
giving the size of the sigset_t. The kernel insists that this
matches its idea of the type size and fails EINVAL if it is not.
Implement this logic in QEMU. (This mostly just means some LTP test
cases which check error cases now pass.)
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
---
linux-user/syscall.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 46 insertions(+), 1 deletion(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 761d8fb..0a99af8 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7978,7 +7978,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#if defined(TARGET_ALPHA)
struct target_sigaction act, oact, *pact = 0;
struct target_rt_sigaction *rt_act;
- /* ??? arg4 == sizeof(sigset_t). */
+
+ if (arg4 != sizeof(target_sigset_t)) {
+ ret = -TARGET_EINVAL;
+ break;
+ }
if (arg2) {
if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
goto efault;
@@ -8002,6 +8006,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
struct target_sigaction *act;
struct target_sigaction *oact;
+ if (arg4 != sizeof(target_sigset_t)) {
+ ret = -TARGET_EINVAL;
+ break;
+ }
if (arg2) {
if (!lock_user_struct(VERIFY_READ, act, arg2, 1))
goto efault;
@@ -8133,6 +8141,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
int how = arg1;
sigset_t set, oldset, *set_ptr;
+ if (arg4 != sizeof(target_sigset_t)) {
+ ret = -TARGET_EINVAL;
+ break;
+ }
+
if (arg2) {
switch(how) {
case TARGET_SIG_BLOCK:
@@ -8183,6 +8196,17 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_rt_sigpending:
{
sigset_t set;
+
+ /* Yes, this check is >, not != like most. We follow the kernel's
+ * logic and it does it like this because it implements
+ * NR_sigpending through the same code path, and in that case
+ * the old_sigset_t is smaller in size.
+ */
+ if (arg2 > sizeof(target_sigset_t)) {
+ ret = -TARGET_EINVAL;
+ break;
+ }
+
ret = get_errno(sigpending(&set));
if (!is_error(ret)) {
if (!(p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0)))
@@ -8216,6 +8240,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_rt_sigsuspend:
{
TaskState *ts = cpu->opaque;
+
+ if (arg2 != sizeof(target_sigset_t)) {
+ ret = -TARGET_EINVAL;
+ break;
+ }
if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
goto efault;
target_to_host_sigset(&ts->sigsuspend_mask, p);
@@ -8233,6 +8262,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
struct timespec uts, *puts;
siginfo_t uinfo;
+ if (arg4 != sizeof(target_sigset_t)) {
+ ret = -TARGET_EINVAL;
+ break;
+ }
+
if (!(p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1)))
goto efault;
target_to_host_sigset(&set, p);
@@ -9484,6 +9518,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
if (arg4) {
+ if (arg5 != sizeof(target_sigset_t)) {
+ unlock_user(target_pfd, arg1, 0);
+ ret = -TARGET_EINVAL;
+ break;
+ }
+
target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1);
if (!target_set) {
unlock_user(target_pfd, arg1, 0);
@@ -11303,6 +11343,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
sigset_t _set, *set = &_set;
if (arg5) {
+ if (arg6 != sizeof(target_sigset_t)) {
+ ret = -TARGET_EINVAL;
+ break;
+ }
+
target_set = lock_user(VERIFY_READ, arg5,
sizeof(target_sigset_t), 1);
if (!target_set) {
--
2.1.4
next prev parent reply other threads:[~2016-07-19 12:54 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-19 12:53 [Qemu-devel] [PULL 00/16] linux-user before 2.7 hardfreeze riku.voipio
2016-07-19 12:53 ` [Qemu-devel] [PULL 01/16] linux-user: fd_trans_*_data() returns the length riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 02/16] linux-user: fix netlink memory corruption riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 03/16] linux-user: add fd_trans helper in do_recvfrom() riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 04/16] linux-user: convert sockaddr_ll from host to target riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 05/16] linux-user: add nested netlink types riku.voipio
2016-07-19 12:54 ` riku.voipio [this message]
2016-07-19 12:54 ` [Qemu-devel] [PULL 07/16] linux-user: Add loop control ioctls riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 08/16] linux-user: Correct type for BLKSSZGET riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 09/16] linux-user: Correct type for LOOP_GET_STATUS{, 64} ioctls riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 10/16] linux-user: Forget about synchronous signal once it is delivered riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 11/16] linux-user: Handle short lengths in host_to_target_sockaddr() riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 12/16] linux-user: Add some new blk ioctls riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 13/16] TIOCGPTN and related terminal control ioctls were not converted to the guest ioctl format on x86_64 targets. Convert these ioctls to enable terminal functionality on x86_64 guests riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 14/16] linux-user: define missing sparc syscalls riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 15/16] linux-user: Fix type for SIOCATMARK ioctl riku.voipio
2016-07-19 12:54 ` [Qemu-devel] [PULL 16/16] linux-user: AArch64 has sync_file_range, not sync_file_range2 riku.voipio
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c815701e8169d25ae6f84183f4b593b9335a9798.1468932683.git.riku.voipio@linaro.org \
--to=riku.voipio@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).