aboutsummaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
authorTimothy E Baldwin <T.E.Baldwin99@members.leeds.ac.uk>2016-05-27 15:51:54 +0100
committerRiku Voipio <riku.voipio@linaro.org>2016-06-07 16:39:07 +0300
commitef6a778ea2af4ebcf08a84cc9314cfe7cf2a2299 (patch)
tree372288a3d559a323da1debc51cd987eaed7938d2 /linux-user
parent655ed67c2a248cf0a887229d8492d6ddc0518545 (diff)
downloadqemu-ef6a778ea2af4ebcf08a84cc9314cfe7cf2a2299.zip
qemu-ef6a778ea2af4ebcf08a84cc9314cfe7cf2a2299.tar.gz
qemu-ef6a778ea2af4ebcf08a84cc9314cfe7cf2a2299.tar.bz2
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.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/linux-user/signal.c b/linux-user/signal.c
index f489028..b21d6bf 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);