diff mbox

[19/34] linux-user: Restart fork() if signals pending

Message ID 1441497448-32489-20-git-send-email-T.E.Baldwin99@members.leeds.ac.uk
State New
Headers show

Commit Message

Timothy Baldwin Sept. 5, 2015, 11:57 p.m. UTC
If there is a signal pending during fork() the signal handler will
erroneously be called in both the parent and child, so handle any
pending signals first.

Signed-off-by: Timothy Edward Baldwin <T.E.Baldwin99@members.leeds.ac.uk>
---
 linux-user/syscall.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Peter Maydell Sept. 11, 2015, 2:34 p.m. UTC | #1
On 6 September 2015 at 00:57, Timothy E Baldwin
<T.E.Baldwin99@members.leeds.ac.uk> wrote:
> If there is a signal pending during fork() the signal handler will
> erroneously be called in both the parent and child, so handle any
> pending signals first.
>
> Signed-off-by: Timothy Edward Baldwin <T.E.Baldwin99@members.leeds.ac.uk>
> ---
>  linux-user/syscall.c | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 682090d..1ce381e 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -4731,6 +4731,11 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
>          if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) {
>              return -TARGET_EINVAL;
>          }
> +
> +        if (block_signals()) {
> +            return -TARGET_ERESTARTSYS;
> +        }
> +
>          fork_start();
>          ret = fork();
>          if (ret == 0) {

This is in the fork part of do_fork(). In the clone part we
have some code which does "block all signals, then arrange to
restore them after the pthread_create in both threads". Can
we change that to work with the new block_signals approach?
(I have a feeling that in that case this call to block_signals
ends up being done earlier so it happens in both halves of
the function.)

If we block all signals here, what causes us to unblock them
again?

thanks
-- PMM
diff mbox

Patch

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 682090d..1ce381e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4731,6 +4731,11 @@  static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
         if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0) {
             return -TARGET_EINVAL;
         }
+
+        if (block_signals()) {
+            return -TARGET_ERESTARTSYS;
+        }
+
         fork_start();
         ret = fork();
         if (ret == 0) {