From: Ian Lance Taylor
+ On Unix systems, functions that use
+ SysProcAttr
+ will now reject attempts to set both the Setctty
+ and Foreground
fields, as they both use
+ the Ctty
field but do so in incompatible ways.
+ We expect that few existing programs set both fields.
+
+ Setting the Setctty
field now requires that the
+ Ctty
field be set to a file descriptor number in the
+ child process, as determined by the ProcAttr.Files
field.
+ Using a child descriptor always worked, but there were certain
+ cases where using a parent file descriptor also happened to work.
+ Some programs that set Setctty
will need to change
+ the value of Ctty
to use a child descriptor number.
+
diff --git a/src/os/signal/signal_cgo_test.go b/src/os/signal/signal_cgo_test.go index 3c23090489..849a96ec0e 100644 --- a/src/os/signal/signal_cgo_test.go +++ b/src/os/signal/signal_cgo_test.go @@ -98,7 +98,7 @@ func TestTerminalSignal(t *testing.T) { cmd.SysProcAttr = &syscall.SysProcAttr{ Setsid: true, Setctty: true, - Ctty: int(slave.Fd()), + Ctty: 0, } if err := cmd.Start(); err != nil { diff --git a/src/syscall/exec_unix.go b/src/syscall/exec_unix.go index b3798b6e04..0345af44f9 100644 --- a/src/syscall/exec_unix.go +++ b/src/syscall/exec_unix.go @@ -9,6 +9,7 @@ package syscall import ( + errorspkg "errors" "internal/bytealg" "runtime" "sync" @@ -187,6 +188,15 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) } } + // Both Setctty and Foreground use the Ctty field, + // but they give it slightly different meanings. + if sys.Setctty && sys.Foreground { + return 0, errorspkg.New("both Setctty and Foreground set in SysProcAttr") + } + if sys.Setctty && sys.Ctty >= len(attr.Files) { + return 0, errorspkg.New("Setctty set but Ctty not valid in child") + } + // Acquire the fork lock so that no other threads // create new fds that are not yet close-on-exec // before we fork. diff --git a/src/syscall/exec_unix_test.go b/src/syscall/exec_unix_test.go index 33614f5221..4eb3c5c6c8 100644 --- a/src/syscall/exec_unix_test.go +++ b/src/syscall/exec_unix_test.go @@ -213,3 +213,31 @@ func TestForeground(t *testing.T) { signal.Reset() } + +// Test a couple of cases that SysProcAttr can't handle. Issue 29458. +func TestInvalidExec(t *testing.T) { + t.Parallel() + t.Run("SetCtty-Foreground", func(t *testing.T) { + t.Parallel() + cmd := create(t) + cmd.proc.SysProcAttr = &syscall.SysProcAttr{ + Setctty: true, + Foreground: true, + Ctty: 0, + } + if err := cmd.proc.Start(); err == nil { + t.Error("expected error setting both SetCtty and Foreground") + } + }) + t.Run("invalid-Ctty", func(t *testing.T) { + t.Parallel() + cmd := create(t) + cmd.proc.SysProcAttr = &syscall.SysProcAttr{ + Setctty: true, + Ctty: 3, + } + if err := cmd.proc.Start(); err == nil { + t.Error("expected error with invalid Ctty value") + } + }) +}