* [PULL 1/2] linux-user: Correct definition of stack_t
2020-11-11 21:40 [PULL 0/2] Linux user for 5.2 patches Laurent Vivier
@ 2020-11-11 21:40 ` Laurent Vivier
2020-11-11 21:40 ` [PULL 2/2] linux-user: Prevent crash in epoll_ctl Laurent Vivier
2020-11-12 11:33 ` [PULL 0/2] Linux user for 5.2 patches Peter Maydell
2 siblings, 0 replies; 4+ messages in thread
From: Laurent Vivier @ 2020-11-11 21:40 UTC (permalink / raw)
To: qemu-devel; +Cc: LemonBoy, Peter Maydell, Laurent Vivier
From: LemonBoy <thatlemon@gmail.com>
Some platforms used the wrong definition of stack_t where the flags and
size fields were swapped or where the flags field had type ulong instead
of int.
Due to the presence of padding space in the structure and the prevalence
of little-endian machines this problem went unnoticed for a long time.
The type definitions have been cross-checked with the ones defined in
the Linux kernel v5.9, plus some older versions for a few architecture
that have been removed and Xilinx's kernel fork for NiosII [1].
The bsd-user headers remain unchanged as I don't know if they are wrong
or not.
[1] https://github.com/Xilinx/linux-xlnx/blob/master/arch/nios2/include/uapi/asm/signal.h
Signed-off-by: Giuseppe Musacchio <thatlemon@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <e9d47692-ee92-009f-6007-0abc3f502b97@gmail.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
linux-user/alpha/target_signal.h | 3 +--
linux-user/arm/target_signal.h | 6 +++---
linux-user/cris/target_signal.h | 6 +++---
linux-user/hppa/target_signal.h | 2 +-
linux-user/i386/target_signal.h | 6 +++---
linux-user/m68k/target_signal.h | 6 +++---
linux-user/microblaze/target_signal.h | 6 +++---
linux-user/mips/target_signal.h | 6 +++---
linux-user/mips64/target_signal.h | 7 +++----
linux-user/nios2/target_signal.h | 5 +++--
linux-user/ppc/target_signal.h | 6 +++---
linux-user/s390x/target_signal.h | 2 +-
linux-user/sh4/target_signal.h | 6 +++---
linux-user/sparc/target_signal.h | 6 +++---
linux-user/x86_64/target_signal.h | 6 +++---
15 files changed, 39 insertions(+), 40 deletions(-)
diff --git a/linux-user/alpha/target_signal.h b/linux-user/alpha/target_signal.h
index cd63d59fdec1..b83797281c32 100644
--- a/linux-user/alpha/target_signal.h
+++ b/linux-user/alpha/target_signal.h
@@ -42,8 +42,7 @@
typedef struct target_sigaltstack {
abi_ulong ss_sp;
- int32_t ss_flags;
- int32_t dummy;
+ abi_int ss_flags;
abi_ulong ss_size;
} target_stack_t;
diff --git a/linux-user/arm/target_signal.h b/linux-user/arm/target_signal.h
index ea123c40f38d..0998dd6dfa75 100644
--- a/linux-user/arm/target_signal.h
+++ b/linux-user/arm/target_signal.h
@@ -4,9 +4,9 @@
/* this struct defines a stack used during syscall handling */
typedef struct target_sigaltstack {
- abi_ulong ss_sp;
- abi_long ss_flags;
- abi_ulong ss_size;
+ abi_ulong ss_sp;
+ abi_int ss_flags;
+ abi_ulong ss_size;
} target_stack_t;
diff --git a/linux-user/cris/target_signal.h b/linux-user/cris/target_signal.h
index 1cb5548f85ea..495a14289681 100644
--- a/linux-user/cris/target_signal.h
+++ b/linux-user/cris/target_signal.h
@@ -4,9 +4,9 @@
/* this struct defines a stack used during syscall handling */
typedef struct target_sigaltstack {
- abi_ulong ss_sp;
- abi_ulong ss_size;
- abi_long ss_flags;
+ abi_ulong ss_sp;
+ abi_int ss_flags;
+ abi_ulong ss_size;
} target_stack_t;
diff --git a/linux-user/hppa/target_signal.h b/linux-user/hppa/target_signal.h
index c2a0102ed73d..c52a3ea5794b 100644
--- a/linux-user/hppa/target_signal.h
+++ b/linux-user/hppa/target_signal.h
@@ -44,7 +44,7 @@
typedef struct target_sigaltstack {
abi_ulong ss_sp;
- int32_t ss_flags;
+ abi_int ss_flags;
abi_ulong ss_size;
} target_stack_t;
diff --git a/linux-user/i386/target_signal.h b/linux-user/i386/target_signal.h
index f55e78fd33e7..50361af8746e 100644
--- a/linux-user/i386/target_signal.h
+++ b/linux-user/i386/target_signal.h
@@ -4,9 +4,9 @@
/* this struct defines a stack used during syscall handling */
typedef struct target_sigaltstack {
- abi_ulong ss_sp;
- abi_long ss_flags;
- abi_ulong ss_size;
+ abi_ulong ss_sp;
+ abi_int ss_flags;
+ abi_ulong ss_size;
} target_stack_t;
diff --git a/linux-user/m68k/target_signal.h b/linux-user/m68k/target_signal.h
index 314e808844a4..d096544ef842 100644
--- a/linux-user/m68k/target_signal.h
+++ b/linux-user/m68k/target_signal.h
@@ -4,9 +4,9 @@
/* this struct defines a stack used during syscall handling */
typedef struct target_sigaltstack {
- abi_ulong ss_sp;
- abi_long ss_flags;
- abi_ulong ss_size;
+ abi_ulong ss_sp;
+ abi_int ss_flags;
+ abi_ulong ss_size;
} target_stack_t;
diff --git a/linux-user/microblaze/target_signal.h b/linux-user/microblaze/target_signal.h
index 08bcf24b9d1c..1c326296de42 100644
--- a/linux-user/microblaze/target_signal.h
+++ b/linux-user/microblaze/target_signal.h
@@ -4,9 +4,9 @@
/* this struct defines a stack used during syscall handling */
typedef struct target_sigaltstack {
- abi_ulong ss_sp;
- abi_ulong ss_size;
- abi_long ss_flags;
+ abi_ulong ss_sp;
+ abi_int ss_flags;
+ abi_ulong ss_size;
} target_stack_t;
diff --git a/linux-user/mips/target_signal.h b/linux-user/mips/target_signal.h
index 66e1ad44a64e..fa4084a99dcd 100644
--- a/linux-user/mips/target_signal.h
+++ b/linux-user/mips/target_signal.h
@@ -45,9 +45,9 @@
/* this struct defines a stack used during syscall handling */
typedef struct target_sigaltstack {
- abi_long ss_sp;
- abi_ulong ss_size;
- abi_long ss_flags;
+ abi_ulong ss_sp;
+ abi_ulong ss_size;
+ abi_int ss_flags;
} target_stack_t;
diff --git a/linux-user/mips64/target_signal.h b/linux-user/mips64/target_signal.h
index 753e91fbd695..799f7a668cd0 100644
--- a/linux-user/mips64/target_signal.h
+++ b/linux-user/mips64/target_signal.h
@@ -45,12 +45,11 @@
/* this struct defines a stack used during syscall handling */
typedef struct target_sigaltstack {
- abi_long ss_sp;
- abi_ulong ss_size;
- abi_int ss_flags;
+ abi_ulong ss_sp;
+ abi_ulong ss_size;
+ abi_int ss_flags;
} target_stack_t;
-
/*
* sigaltstack controls
*/
diff --git a/linux-user/nios2/target_signal.h b/linux-user/nios2/target_signal.h
index fe48721b3db0..aebf749f1278 100644
--- a/linux-user/nios2/target_signal.h
+++ b/linux-user/nios2/target_signal.h
@@ -4,11 +4,12 @@
/* this struct defines a stack used during syscall handling */
typedef struct target_sigaltstack {
- abi_long ss_sp;
+ abi_ulong ss_sp;
+ abi_int ss_flags;
abi_ulong ss_size;
- abi_long ss_flags;
} target_stack_t;
+
/* sigaltstack controls */
#define TARGET_SS_ONSTACK 1
#define TARGET_SS_DISABLE 2
diff --git a/linux-user/ppc/target_signal.h b/linux-user/ppc/target_signal.h
index 4453e2e7efd7..72fcdd9bfa20 100644
--- a/linux-user/ppc/target_signal.h
+++ b/linux-user/ppc/target_signal.h
@@ -4,9 +4,9 @@
/* this struct defines a stack used during syscall handling */
typedef struct target_sigaltstack {
- abi_ulong ss_sp;
- int ss_flags;
- abi_ulong ss_size;
+ abi_ulong ss_sp;
+ abi_int ss_flags;
+ abi_ulong ss_size;
} target_stack_t;
diff --git a/linux-user/s390x/target_signal.h b/linux-user/s390x/target_signal.h
index b58bc7c20f63..bbfc464d4417 100644
--- a/linux-user/s390x/target_signal.h
+++ b/linux-user/s390x/target_signal.h
@@ -3,7 +3,7 @@
typedef struct target_sigaltstack {
abi_ulong ss_sp;
- int ss_flags;
+ abi_int ss_flags;
abi_ulong ss_size;
} target_stack_t;
diff --git a/linux-user/sh4/target_signal.h b/linux-user/sh4/target_signal.h
index 434970a9900a..d7309b7136d7 100644
--- a/linux-user/sh4/target_signal.h
+++ b/linux-user/sh4/target_signal.h
@@ -4,9 +4,9 @@
/* this struct defines a stack used during syscall handling */
typedef struct target_sigaltstack {
- abi_ulong ss_sp;
- abi_long ss_flags;
- abi_ulong ss_size;
+ abi_ulong ss_sp;
+ abi_int ss_flags;
+ abi_ulong ss_size;
} target_stack_t;
diff --git a/linux-user/sparc/target_signal.h b/linux-user/sparc/target_signal.h
index 5cc40327d2c2..1b10d1490fc9 100644
--- a/linux-user/sparc/target_signal.h
+++ b/linux-user/sparc/target_signal.h
@@ -42,9 +42,9 @@
/* this struct defines a stack used during syscall handling */
typedef struct target_sigaltstack {
- abi_ulong ss_sp;
- abi_long ss_flags;
- abi_ulong ss_size;
+ abi_ulong ss_sp;
+ abi_int ss_flags;
+ abi_ulong ss_size;
} target_stack_t;
diff --git a/linux-user/x86_64/target_signal.h b/linux-user/x86_64/target_signal.h
index 4c4380f7b949..4ea74f20dd42 100644
--- a/linux-user/x86_64/target_signal.h
+++ b/linux-user/x86_64/target_signal.h
@@ -4,9 +4,9 @@
/* this struct defines a stack used during syscall handling */
typedef struct target_sigaltstack {
- abi_ulong ss_sp;
- abi_long ss_flags;
- abi_ulong ss_size;
+ abi_ulong ss_sp;
+ abi_int ss_flags;
+ abi_ulong ss_size;
} target_stack_t;
--
2.28.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PULL 2/2] linux-user: Prevent crash in epoll_ctl
2020-11-11 21:40 [PULL 0/2] Linux user for 5.2 patches Laurent Vivier
2020-11-11 21:40 ` [PULL 1/2] linux-user: Correct definition of stack_t Laurent Vivier
@ 2020-11-11 21:40 ` Laurent Vivier
2020-11-12 11:33 ` [PULL 0/2] Linux user for 5.2 patches Peter Maydell
2 siblings, 0 replies; 4+ messages in thread
From: Laurent Vivier @ 2020-11-11 21:40 UTC (permalink / raw)
To: qemu-devel; +Cc: LemonBoy, Laurent Vivier
From: LemonBoy <thatlemon@gmail.com>
From 894bb5172705e46a3a04c93b4962c0f0cafee814 Mon Sep 17 00:00:00 2001
From: Giuseppe Musacchio <thatlemon@gmail.com>
Date: Fri, 17 Apr 2020 17:25:07 +0200
Subject: [PATCH] linux-user: Prevent crash in epoll_ctl
The `event` parameter is ignored by the kernel if `op` is EPOLL_CTL_DEL,
do the same and avoid returning EFAULT if garbage is passed instead of a
valid pointer.
Signed-off-by: Giuseppe Musacchio <thatlemon@gmail.com>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <a244fa67-dace-abdb-995a-3198bd80fee8@gmail.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
linux-user/syscall.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 3160a9ba06bd..27adee908ebc 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -12590,17 +12590,25 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
struct epoll_event ep;
struct epoll_event *epp = 0;
if (arg4) {
- struct target_epoll_event *target_ep;
- if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
- return -TARGET_EFAULT;
+ if (arg2 != EPOLL_CTL_DEL) {
+ struct target_epoll_event *target_ep;
+ if (!lock_user_struct(VERIFY_READ, target_ep, arg4, 1)) {
+ return -TARGET_EFAULT;
+ }
+ ep.events = tswap32(target_ep->events);
+ /*
+ * The epoll_data_t union is just opaque data to the kernel,
+ * so we transfer all 64 bits across and need not worry what
+ * actual data type it is.
+ */
+ ep.data.u64 = tswap64(target_ep->data.u64);
+ unlock_user_struct(target_ep, arg4, 0);
}
- ep.events = tswap32(target_ep->events);
- /* The epoll_data_t union is just opaque data to the kernel,
- * so we transfer all 64 bits across and need not worry what
- * actual data type it is.
+ /*
+ * before kernel 2.6.9, EPOLL_CTL_DEL operation required a
+ * non-null pointer, even though this argument is ignored.
+ *
*/
- ep.data.u64 = tswap64(target_ep->data.u64);
- unlock_user_struct(target_ep, arg4, 0);
epp = &ep;
}
return get_errno(epoll_ctl(arg1, arg2, arg3, epp));
--
2.28.0
^ permalink raw reply related [flat|nested] 4+ messages in thread