qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 0/1] Linux user for 4.1 patches
@ 2019-07-26 17:35 Laurent Vivier
  2019-07-26 17:35 ` [Qemu-devel] [PULL 1/1] linux-user: Make sigaltstack stacks per-thread Laurent Vivier
  2019-07-29  9:14 ` [Qemu-devel] [PULL 0/1] Linux user for 4.1 patches Peter Maydell
  0 siblings, 2 replies; 3+ messages in thread
From: Laurent Vivier @ 2019-07-26 17:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio, Laurent Vivier

The following changes since commit fff3159900d2b95613a9cb75fc3703e67a674729:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20190726' into staging (2019-07-26 16:23:07 +0100)

are available in the Git repository at:

  git://github.com/vivier/qemu.git tags/linux-user-for-4.1-pull-request

for you to fetch changes up to 5bfce0b74fbd5d53089bb866919d685c47edad9e:

  linux-user: Make sigaltstack stacks per-thread (2019-07-26 19:24:33 +0200)

----------------------------------------------------------------
Fix multi-threaded go runtime crash

----------------------------------------------------------------

Peter Maydell (1):
  linux-user: Make sigaltstack stacks per-thread

 linux-user/hppa/signal.c   |  3 ++-
 linux-user/main.c          |  5 +++++
 linux-user/qemu.h          |  2 ++
 linux-user/signal-common.h |  1 -
 linux-user/signal.c        | 35 +++++++++++++++++++----------------
 5 files changed, 28 insertions(+), 18 deletions(-)

-- 
2.21.0



^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Qemu-devel] [PULL 1/1] linux-user: Make sigaltstack stacks per-thread
  2019-07-26 17:35 [Qemu-devel] [PULL 0/1] Linux user for 4.1 patches Laurent Vivier
@ 2019-07-26 17:35 ` Laurent Vivier
  2019-07-29  9:14 ` [Qemu-devel] [PULL 0/1] Linux user for 4.1 patches Peter Maydell
  1 sibling, 0 replies; 3+ messages in thread
From: Laurent Vivier @ 2019-07-26 17:35 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Riku Voipio, Richard Henderson, Laurent Vivier

From: Peter Maydell <peter.maydell@linaro.org>

The alternate signal stack set up by the sigaltstack syscall is
supposed to be per-thread.  We were incorrectly implementing it as
process-wide.  This causes problems for guest binaries that rely on
this.  Notably the Go runtime does, and so we were seeing crashes
caused by races where two guest threads might incorrectly both
execute on the same stack simultaneously.

Replace the global target_sigaltstack_used with a field
sigaltstack_used in the TaskState, and make all the references to the
old global instead get a pointer to the TaskState and use the field.

Fixes: https://bugs.launchpad.net/qemu/+bug/1696773
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <20190725131645.19501-1-peter.maydell@linaro.org>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 linux-user/hppa/signal.c   |  3 ++-
 linux-user/main.c          |  5 +++++
 linux-user/qemu.h          |  2 ++
 linux-user/signal-common.h |  1 -
 linux-user/signal.c        | 35 +++++++++++++++++++----------------
 5 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/linux-user/hppa/signal.c b/linux-user/hppa/signal.c
index b6927ee67351..d1a58feeb36f 100644
--- a/linux-user/hppa/signal.c
+++ b/linux-user/hppa/signal.c
@@ -111,10 +111,11 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
     abi_ulong frame_addr, sp, haddr;
     struct target_rt_sigframe *frame;
     int i;
+    TaskState *ts = (TaskState *)thread_cpu->opaque;
 
     sp = get_sp_from_cpustate(env);
     if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) {
-        sp = (target_sigaltstack_used.ss_sp + 0x7f) & ~0x3f;
+        sp = (ts->sigaltstack_used.ss_sp + 0x7f) & ~0x3f;
     }
     frame_addr = QEMU_ALIGN_UP(sp, 64);
     sp = frame_addr + PARISC_RT_SIGFRAME_SIZE32;
diff --git a/linux-user/main.c b/linux-user/main.c
index a59ae9439de1..8ffc52519552 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -180,6 +180,11 @@ void stop_all_tasks(void)
 void init_task_state(TaskState *ts)
 {
     ts->used = 1;
+    ts->sigaltstack_used = (struct target_sigaltstack) {
+        .ss_sp = 0,
+        .ss_size = 0,
+        .ss_flags = TARGET_SS_DISABLE,
+    };
 }
 
 CPUArchState *cpu_copy(CPUArchState *env)
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 4258e4162d26..aac033462700 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -151,6 +151,8 @@ typedef struct TaskState {
      */
     int signal_pending;
 
+    /* This thread's sigaltstack, if it has one */
+    struct target_sigaltstack sigaltstack_used;
 } __attribute__((aligned(16))) TaskState;
 
 extern char *exec_path;
diff --git a/linux-user/signal-common.h b/linux-user/signal-common.h
index 51030a93069a..1df1068552fb 100644
--- a/linux-user/signal-common.h
+++ b/linux-user/signal-common.h
@@ -19,7 +19,6 @@
 
 #ifndef SIGNAL_COMMON_H
 #define SIGNAL_COMMON_H
-extern struct target_sigaltstack target_sigaltstack_used;
 
 int on_sig_stack(unsigned long sp);
 int sas_ss_flags(unsigned long sp);
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 5cd237834d9a..5ca6d62b15d3 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -25,12 +25,6 @@
 #include "trace.h"
 #include "signal-common.h"
 
-struct target_sigaltstack target_sigaltstack_used = {
-    .ss_sp = 0,
-    .ss_size = 0,
-    .ss_flags = TARGET_SS_DISABLE,
-};
-
 static struct target_sigaction sigact_table[TARGET_NSIG];
 
 static void host_signal_handler(int host_signum, siginfo_t *info,
@@ -251,13 +245,17 @@ void set_sigmask(const sigset_t *set)
 
 int on_sig_stack(unsigned long sp)
 {
-    return (sp - target_sigaltstack_used.ss_sp
-            < target_sigaltstack_used.ss_size);
+    TaskState *ts = (TaskState *)thread_cpu->opaque;
+
+    return (sp - ts->sigaltstack_used.ss_sp
+            < ts->sigaltstack_used.ss_size);
 }
 
 int sas_ss_flags(unsigned long sp)
 {
-    return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
+    TaskState *ts = (TaskState *)thread_cpu->opaque;
+
+    return (ts->sigaltstack_used.ss_size == 0 ? SS_DISABLE
             : on_sig_stack(sp) ? SS_ONSTACK : 0);
 }
 
@@ -266,17 +264,21 @@ abi_ulong target_sigsp(abi_ulong sp, struct target_sigaction *ka)
     /*
      * This is the X/Open sanctioned signal stack switching.
      */
+    TaskState *ts = (TaskState *)thread_cpu->opaque;
+
     if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) {
-        return target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
+        return ts->sigaltstack_used.ss_sp + ts->sigaltstack_used.ss_size;
     }
     return sp;
 }
 
 void target_save_altstack(target_stack_t *uss, CPUArchState *env)
 {
-    __put_user(target_sigaltstack_used.ss_sp, &uss->ss_sp);
+    TaskState *ts = (TaskState *)thread_cpu->opaque;
+
+    __put_user(ts->sigaltstack_used.ss_sp, &uss->ss_sp);
     __put_user(sas_ss_flags(get_sp_from_cpustate(env)), &uss->ss_flags);
-    __put_user(target_sigaltstack_used.ss_size, &uss->ss_size);
+    __put_user(ts->sigaltstack_used.ss_size, &uss->ss_size);
 }
 
 /* siginfo conversion */
@@ -708,12 +710,13 @@ abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
 {
     int ret;
     struct target_sigaltstack oss;
+    TaskState *ts = (TaskState *)thread_cpu->opaque;
 
     /* XXX: test errors */
     if(uoss_addr)
     {
-        __put_user(target_sigaltstack_used.ss_sp, &oss.ss_sp);
-        __put_user(target_sigaltstack_used.ss_size, &oss.ss_size);
+        __put_user(ts->sigaltstack_used.ss_sp, &oss.ss_sp);
+        __put_user(ts->sigaltstack_used.ss_size, &oss.ss_size);
         __put_user(sas_ss_flags(sp), &oss.ss_flags);
     }
 
@@ -760,8 +763,8 @@ abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
             }
         }
 
-        target_sigaltstack_used.ss_sp = ss.ss_sp;
-        target_sigaltstack_used.ss_size = ss.ss_size;
+        ts->sigaltstack_used.ss_sp = ss.ss_sp;
+        ts->sigaltstack_used.ss_size = ss.ss_size;
     }
 
     if (uoss_addr) {
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [PULL 0/1] Linux user for 4.1 patches
  2019-07-26 17:35 [Qemu-devel] [PULL 0/1] Linux user for 4.1 patches Laurent Vivier
  2019-07-26 17:35 ` [Qemu-devel] [PULL 1/1] linux-user: Make sigaltstack stacks per-thread Laurent Vivier
@ 2019-07-29  9:14 ` Peter Maydell
  1 sibling, 0 replies; 3+ messages in thread
From: Peter Maydell @ 2019-07-29  9:14 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: Riku Voipio, QEMU Developers

On Fri, 26 Jul 2019 at 18:35, Laurent Vivier <laurent@vivier.eu> wrote:
>
> The following changes since commit fff3159900d2b95613a9cb75fc3703e67a674729:
>
>   Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20190726' into staging (2019-07-26 16:23:07 +0100)
>
> are available in the Git repository at:
>
>   git://github.com/vivier/qemu.git tags/linux-user-for-4.1-pull-request
>
> for you to fetch changes up to 5bfce0b74fbd5d53089bb866919d685c47edad9e:
>
>   linux-user: Make sigaltstack stacks per-thread (2019-07-26 19:24:33 +0200)
>
> ----------------------------------------------------------------
> Fix multi-threaded go runtime crash
>
> ----------------------------------------------------------------


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/4.1
for any user-visible changes.

-- PMM


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-07-29  9:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-26 17:35 [Qemu-devel] [PULL 0/1] Linux user for 4.1 patches Laurent Vivier
2019-07-26 17:35 ` [Qemu-devel] [PULL 1/1] linux-user: Make sigaltstack stacks per-thread Laurent Vivier
2019-07-29  9:14 ` [Qemu-devel] [PULL 0/1] Linux user for 4.1 patches Peter Maydell

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).