diff mbox

[PULL,18/44] linux-user: pause() should not pause if signal pending

Message ID f59ec606104ade2443179231fc7a3cb98683ac85.1465392531.git.riku.voipio@linaro.org (mailing list archive)
State New, archived
Headers show

Commit Message

Riku Voipio June 8, 2016, 1:29 p.m. UTC
From: Timothy E Baldwin <T.E.Baldwin99@members.leeds.ac.uk>

Fix races between signal handling and the pause syscall by
reimplementing it using block_signals() and sigsuspend().
(Using safe_syscall(pause) would also work, except that the
pause syscall doesn't exist on all architectures.)

Signed-off-by: Timothy Edward Baldwin <T.E.Baldwin99@members.leeds.ac.uk>
Message-id: 1441497448-32489-28-git-send-email-T.E.Baldwin99@members.leeds.ac.uk
[PMM: tweaked commit message]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
---
 linux-user/syscall.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 639b328..aa5517c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7059,7 +7059,10 @@  abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_pause /* not on alpha */
     case TARGET_NR_pause:
-        ret = get_errno(pause());
+        if (!block_signals()) {
+            sigsuspend(&((TaskState *)cpu->opaque)->signal_mask);
+        }
+        ret = -TARGET_EINTR;
         break;
 #endif
 #ifdef TARGET_NR_utime