aboutsummaryrefslogtreecommitdiff
path: root/src/syscall/exec_linux.go
diff options
context:
space:
mode:
authorKir Kolyshkin <kolyshkin@gmail.com>2023-11-16 00:42:04 -0800
committerGopher Robot <gobot@golang.org>2023-11-21 20:13:01 +0000
commitf7b2779086683bf00570427ce08bebfb54c53b76 (patch)
tree6b7e887b97026e751c4b8df78622185074e07293 /src/syscall/exec_linux.go
parentcfb281754ec94859e86962ee3a66b8347e3161ab (diff)
downloadgo-f7b2779086683bf00570427ce08bebfb54c53b76.tar.xz
syscall: fix getting pidfd when using CLONE_NEWUSER
While working on CL 528798, I found out that sys.PidFD field (added in CL 520266) is not filled in when CLONE_NEWUSER is used. This happens because the code assumed that the parent and the child run in the same memory space. This assumption is right only when CLONE_VM is used for clone syscall, and the code only sets CLONE_VM when CLONE_NEWUSER is not used. Fix this, and add a test case (which fails before the fix). Updates #51246. Change-Id: I805203c1369cadd63d769568b132a9ffd92cc184 Reviewed-on: https://go-review.googlesource.com/c/go/+/542698 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> Auto-Submit: Michael Pratt <mpratt@google.com>
Diffstat (limited to 'src/syscall/exec_linux.go')
-rw-r--r--src/syscall/exec_linux.go13
1 files changed, 6 insertions, 7 deletions
diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
index e1c71b5a34..e6d6343ed8 100644
--- a/src/syscall/exec_linux.go
+++ b/src/syscall/exec_linux.go
@@ -133,7 +133,7 @@ func runtime_AfterForkInChild()
func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) {
// Set up and fork. This returns immediately in the parent or
// if there's an error.
- upid, err, mapPipe, locked := forkAndExecInChild1(argv0, argv, envv, chroot, dir, attr, sys, pipe)
+ upid, pidfd, err, mapPipe, locked := forkAndExecInChild1(argv0, argv, envv, chroot, dir, attr, sys, pipe)
if locked {
runtime_AfterFork()
}
@@ -143,6 +143,9 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
// parent; return PID
pid = int(upid)
+ if sys.PidFD != nil {
+ *sys.PidFD = int(pidfd)
+ }
if sys.UidMappings != nil || sys.GidMappings != nil {
Close(mapPipe[0])
@@ -210,7 +213,7 @@ type cloneArgs struct {
//go:noinline
//go:norace
//go:nocheckptr
-func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid uintptr, err1 Errno, mapPipe [2]int, locked bool) {
+func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid uintptr, pidfd int32, err1 Errno, mapPipe [2]int, locked bool) {
// Defined in linux/prctl.h starting with Linux 4.3.
const (
PR_CAP_AMBIENT = 0x2f
@@ -241,12 +244,12 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att
uidmap, setgroups, gidmap []byte
clone3 *cloneArgs
pgrp int32
- pidfd _C_int = -1
dirfd int
cred *Credential
ngroups, groups uintptr
c uintptr
)
+ pidfd = -1
rlim := origRlimitNofile.Load()
@@ -341,10 +344,6 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att
// Fork succeeded, now in child.
- if sys.PidFD != nil {
- *sys.PidFD = int(pidfd)
- }
-
// 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)