diff options
author | Ian Lance Taylor <iant@golang.org> | 2021-04-26 17:27:58 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2021-04-27 13:50:09 +0000 |
commit | 7d22c2181b4343b58e40962cefd52af1284b4294 (patch) | |
tree | d8e975ccc9e6b025930e8ce173654e65774eb824 /src/syscall | |
parent | 39844971fb92992305babb4b64d50faa7fea40a0 (diff) | |
download | go-7d22c2181b4343b58e40962cefd52af1284b4294.tar.gz go-7d22c2181b4343b58e40962cefd52af1284b4294.zip |
syscall: restore signal mask after setting foreground process group
Fixes #37217
Change-Id: I0151bb77fc4c4552d1b19c31d784943b72f84b80
Reviewed-on: https://go-review.googlesource.com/c/go/+/313653
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
Diffstat (limited to 'src/syscall')
-rw-r--r-- | src/syscall/exec_bsd.go | 6 | ||||
-rw-r--r-- | src/syscall/exec_libc.go | 6 | ||||
-rw-r--r-- | src/syscall/exec_libc2.go | 6 | ||||
-rw-r--r-- | src/syscall/exec_linux.go | 6 | ||||
-rw-r--r-- | src/syscall/exec_unix_test.go | 41 |
5 files changed, 56 insertions, 9 deletions
diff --git a/src/syscall/exec_bsd.go b/src/syscall/exec_bsd.go index 9c1fbbaeab..051d130459 100644 --- a/src/syscall/exec_bsd.go +++ b/src/syscall/exec_bsd.go @@ -90,8 +90,6 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr // Fork succeeded, now in child. - runtime_AfterForkInChild() - // Enable tracing if requested. if sys.Ptrace { _, _, err1 = RawSyscall(SYS_PTRACE, uintptr(PTRACE_TRACEME), 0, 0) @@ -137,6 +135,10 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr } } + // Restore the signal mask. We do this after TIOCSPGRP to avoid + // having the kernel send a SIGTTOU signal to the process group. + runtime_AfterForkInChild() + // Chroot if chroot != nil { _, _, err1 = RawSyscall(SYS_CHROOT, uintptr(unsafe.Pointer(chroot)), 0, 0) diff --git a/src/syscall/exec_libc.go b/src/syscall/exec_libc.go index 3c8e87d32f..8a84954051 100644 --- a/src/syscall/exec_libc.go +++ b/src/syscall/exec_libc.go @@ -116,8 +116,6 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr // Fork succeeded, now in child. - runtime_AfterForkInChild() - // Session ID if sys.Setsid { _, err1 = setsid() @@ -153,6 +151,10 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr } } + // Restore the signal mask. We do this after TIOCSPGRP to avoid + // having the kernel send a SIGTTOU signal to the process group. + runtime_AfterForkInChild() + // Chroot if chroot != nil { err1 = chroot1(uintptr(unsafe.Pointer(chroot))) diff --git a/src/syscall/exec_libc2.go b/src/syscall/exec_libc2.go index 37df790193..61b1a226eb 100644 --- a/src/syscall/exec_libc2.go +++ b/src/syscall/exec_libc2.go @@ -91,8 +91,6 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr // Fork succeeded, now in child. - runtime_AfterForkInChild() - // Enable tracing if requested. if sys.Ptrace { if err := ptrace(PTRACE_TRACEME, 0, 0, 0); err != nil { @@ -136,6 +134,10 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr } } + // Restore the signal mask. We do this after TIOCSPGRP to avoid + // having the kernel send a SIGTTOU signal to the process group. + runtime_AfterForkInChild() + // Chroot if chroot != nil { _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_chroot_trampoline), uintptr(unsafe.Pointer(chroot)), 0, 0) diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go index deb8aa38b7..ccc0e39e30 100644 --- a/src/syscall/exec_linux.go +++ b/src/syscall/exec_linux.go @@ -233,8 +233,6 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att // Fork succeeded, now in child. - runtime_AfterForkInChild() - // Enable the "keep capabilities" flag to set ambient capabilities later. if len(sys.AmbientCaps) > 0 { _, _, err1 = RawSyscall6(SYS_PRCTL, PR_SET_KEEPCAPS, 1, 0, 0, 0, 0) @@ -294,6 +292,10 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att } } + // Restore the signal mask. We do this after TIOCSPGRP to avoid + // having the kernel send a SIGTTOU signal to the process group. + runtime_AfterForkInChild() + // Unshare if sys.Unshareflags != 0 { _, _, err1 = RawSyscall(SYS_UNSHARE, sys.Unshareflags, 0, 0) diff --git a/src/syscall/exec_unix_test.go b/src/syscall/exec_unix_test.go index 10bad5ac46..643c2e9789 100644 --- a/src/syscall/exec_unix_test.go +++ b/src/syscall/exec_unix_test.go @@ -167,11 +167,13 @@ func TestPgid(t *testing.T) { func TestForeground(t *testing.T) { signal.Ignore(syscall.SIGTTIN, syscall.SIGTTOU) + defer signal.Reset() tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0) if err != nil { t.Skipf("Can't test Foreground. Couldn't open /dev/tty: %s", err) } + defer tty.Close() // This should really be pid_t, however _C_int (aka int32) is generally // equivalent. @@ -216,8 +218,45 @@ func TestForeground(t *testing.T) { if errno != 0 { t.Fatalf("TIOCSPGRP failed with error code: %s", errno) } +} + +func TestForegroundSignal(t *testing.T) { + tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0) + if err != nil { + t.Skipf("couldn't open /dev/tty: %s", err) + } + defer tty.Close() + + ch1 := make(chan os.Signal, 1) + ch2 := make(chan bool) + + signal.Notify(ch1, syscall.SIGTTIN, syscall.SIGTTOU) + defer signal.Stop(ch1) - signal.Reset() + go func() { + cmd := create(t) + cmd.proc.SysProcAttr = &syscall.SysProcAttr{ + Ctty: int(tty.Fd()), + Foreground: true, + } + cmd.Start() + cmd.Stop() + close(ch2) + }() + + timer := time.NewTimer(30 * time.Second) + defer timer.Stop() + for { + select { + case sig := <-ch1: + t.Errorf("unexpected signal %v", sig) + case <-ch2: + // Success. + return + case <-timer.C: + t.Fatal("timed out waiting for child process") + } + } } // Test a couple of cases that SysProcAttr can't handle. Issue 29458. |