diff options
| author | Andrew Williams <williams.andrew@gmail.com> | 2015-01-25 12:53:34 -0600 |
|---|---|---|
| committer | Ian Lance Taylor <iant@golang.org> | 2015-05-12 19:34:46 +0000 |
| commit | 9b379d7e04750bbf6615cdfc1783db53c3d9bdc9 (patch) | |
| tree | 43b1785090d046177cf32da1ff3115d8dacb493c /src/syscall/exec_linux.go | |
| parent | 8552047a32cccccc1c376e49048c5a22494b7611 (diff) | |
| download | go-9b379d7e04750bbf6615cdfc1783db53c3d9bdc9.tar.xz | |
syscall: relocate linux death signal code
Fix bug on Linux SysProcAttr handling: setting both Pdeathsig and
Credential caused Pdeathsig to be ignored. This is because the kernel
clears the deathsignal field when performing a setuid/setgid
system call.
Avoid this by moving Pdeathsig handling after Credential handling.
Fixes #9686
Change-Id: Id01896ad4e979b8c448e0061f00aa8762ca0ac94
Reviewed-on: https://go-review.googlesource.com/3290
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/syscall/exec_linux.go')
| -rw-r--r-- | src/syscall/exec_linux.go | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go index ced2ca862d..3aa30c7364 100644 --- a/src/syscall/exec_linux.go +++ b/src/syscall/exec_linux.go @@ -132,26 +132,6 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr } } - // Parent death signal - if sys.Pdeathsig != 0 { - _, _, err1 = RawSyscall6(SYS_PRCTL, PR_SET_PDEATHSIG, uintptr(sys.Pdeathsig), 0, 0, 0, 0) - if err1 != 0 { - goto childerror - } - - // Signal self if parent is already dead. This might cause a - // duplicate signal in rare cases, but it won't matter when - // using SIGKILL. - r1, _, _ = RawSyscall(SYS_GETPPID, 0, 0, 0) - if r1 != ppid { - pid, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) - _, _, err1 := RawSyscall(SYS_KILL, pid, uintptr(sys.Pdeathsig), 0) - if err1 != 0 { - goto childerror - } - } - } - // Enable tracing if requested. if sys.Ptrace { _, _, err1 = RawSyscall(SYS_PTRACE, uintptr(PTRACE_TRACEME), 0, 0) @@ -232,6 +212,26 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr } } + // Parent death signal + if sys.Pdeathsig != 0 { + _, _, err1 = RawSyscall6(SYS_PRCTL, PR_SET_PDEATHSIG, uintptr(sys.Pdeathsig), 0, 0, 0, 0) + if err1 != 0 { + goto childerror + } + + // Signal self if parent is already dead. This might cause a + // duplicate signal in rare cases, but it won't matter when + // using SIGKILL. + r1, _, _ = RawSyscall(SYS_GETPPID, 0, 0, 0) + if r1 != ppid { + pid, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0) + _, _, err1 := RawSyscall(SYS_KILL, pid, uintptr(sys.Pdeathsig), 0) + if err1 != 0 { + goto childerror + } + } + } + // Pass 1: look for fd[i] < i and move those up above len(fd) // so that pass 2 won't stomp on an fd it needs later. if pipe < nextfd { |
