]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: restore signal mask after setting foreground process group
authorIan Lance Taylor <iant@golang.org>
Tue, 27 Apr 2021 00:27:58 +0000 (17:27 -0700)
committerIan Lance Taylor <iant@golang.org>
Tue, 27 Apr 2021 13:50:09 +0000 (13:50 +0000)
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>
src/syscall/exec_bsd.go
src/syscall/exec_libc.go
src/syscall/exec_libc2.go
src/syscall/exec_linux.go
src/syscall/exec_unix_test.go

index 9c1fbbaeab02f73fdd7ff02c06674ab5cd08fb42..051d130459a90b75e03e51af40b8f6c101496b6f 100644 (file)
@@ -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)
index 3c8e87d32f05c3c183bbe113bd935c68f492919c..8a84954051a1dc42526fe78e85004d158aac5738 100644 (file)
@@ -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)))
index 37df790193be0146bc48eae626534b78163cfaf6..61b1a226ebbe03c6c61838f16d1293cf1a944c83 100644 (file)
@@ -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)
index deb8aa38b704929ad95cc56969f894e3faec9c09..ccc0e39e30bda23cb5f7093b750c6562af14bc40 100644 (file)
@@ -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)
index 10bad5ac468d5b19c1d576725656b8cce39b466d..643c2e978911ac412ff17653ec597a04e337e859 100644 (file)
@@ -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.