diff options
| author | Timothy E Baldwin | 2016-05-27 16:51:54 +0200 |
|---|---|---|
| committer | Riku Voipio | 2016-06-07 15:39:07 +0200 |
| commit | ef6a778ea2af4ebcf08a84cc9314cfe7cf2a2299 (patch) | |
| tree | 372288a3d559a323da1debc51cd987eaed7938d2 /linux-user | |
| parent | linux-user: Queue synchronous signals separately (diff) | |
| download | qemu-ef6a778ea2af4ebcf08a84cc9314cfe7cf2a2299.tar.gz qemu-ef6a778ea2af4ebcf08a84cc9314cfe7cf2a2299.tar.xz qemu-ef6a778ea2af4ebcf08a84cc9314cfe7cf2a2299.zip | |
linux-user: Block signals during sigaction() handling
Block signals while emulating sigaction. This is a non-interruptible
syscall, and using block_signals() avoids races where the host
signal handler is invoked and tries to examine the signal handler
data structures while we are updating them.
Signed-off-by: Timothy Edward Baldwin <T.E.Baldwin99@members.leeds.ac.uk>
Message-id: 1441497448-32489-29-git-send-email-T.E.Baldwin99@members.leeds.ac.uk
[PMM: expanded 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>
Diffstat (limited to 'linux-user')
| -rw-r--r-- | linux-user/signal.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/linux-user/signal.c b/linux-user/signal.c index f48902882d..b21d6bf625 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -640,7 +640,7 @@ out: return ret; } -/* do_sigaction() return host values and errnos */ +/* do_sigaction() return target values and host errnos */ int do_sigaction(int sig, const struct target_sigaction *act, struct target_sigaction *oact) { @@ -649,8 +649,14 @@ int do_sigaction(int sig, const struct target_sigaction *act, int host_sig; int ret = 0; - if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP) - return -EINVAL; + if (sig < 1 || sig > TARGET_NSIG || sig == TARGET_SIGKILL || sig == TARGET_SIGSTOP) { + return -TARGET_EINVAL; + } + + if (block_signals()) { + return -TARGET_ERESTARTSYS; + } + k = &sigact_table[sig - 1]; if (oact) { __put_user(k->_sa_handler, &oact->_sa_handler); |
