Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mrunalp/7334e74a01b9a10e8546 to your computer and use it in GitHub Desktop.
Save mrunalp/7334e74a01b9a10e8546 to your computer and use it in GitHub Desktop.
diff -r 9895f9e36435 src/pkg/syscall/exec_linux.go
--- a/src/pkg/syscall/exec_linux.go Thu Jun 19 10:20:01 2014 +1000
+++ b/src/pkg/syscall/exec_linux.go Wed Jul 30 14:03:39 2014 -0400
@@ -36,7 +36,7 @@
// For the same reason compiler does not race instrument it.
// The calls to RawSyscall are okay because they are assembly
// functions that do not grow the stack.
-func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) {
+func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, child, parent int) (pid int, err Errno) {
// Declare all variables at top in case any
// declarations require heap allocation (e.g., err1).
var (
@@ -44,6 +44,7 @@
err1 Errno
nextfd int
i int
+ lzero uintptr
)
// Guard against side effects of shuffling fds below.
@@ -75,6 +76,16 @@
}
// Fork succeeded, now in child.
+ if _, _, err1 = RawSyscall(SYS_CLOSE, uintptr(child), 0, 0); err != 0 {
+ goto childerror
+ }
+
+ if sys.Credential != nil && (sys.Credential.UidMappings != "" || sys.Credential.GidMappings != "") {
+ _, _, err1 = RawSyscall(SYS_READ, uintptr(parent), uintptr(unsafe.Pointer(&lzero)), uintptr(1))
+ if err1 != 0 {
+ goto childerror
+ }
+ }
// Parent death signal
if sys.Pdeathsig != 0 {
@@ -159,13 +170,13 @@
// 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 {
- _, _, err1 = RawSyscall(SYS_DUP2, uintptr(pipe), uintptr(nextfd), 0)
+ if child < nextfd {
+ _, _, err1 = RawSyscall(SYS_DUP2, uintptr(child), uintptr(nextfd), 0)
if err1 != 0 {
goto childerror
}
RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
- pipe = nextfd
+ child = nextfd
nextfd++
}
for i = 0; i < len(fd); i++ {
@@ -177,7 +188,7 @@
RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
fd[i] = nextfd
nextfd++
- if nextfd == pipe { // don't stomp on pipe
+ if nextfd == child { // don't stomp on pipe
nextfd++
}
}
@@ -237,8 +248,8 @@
uintptr(unsafe.Pointer(&envv[0])))
childerror:
- // send error code on pipe
- RawSyscall(SYS_WRITE, uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
+ // send error code on child
+ RawSyscall(SYS_WRITE, uintptr(child), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
for {
RawSyscall(SYS_EXIT, 253, 0, 0)
}
diff -r 9895f9e36435 src/pkg/syscall/exec_unix.go
--- a/src/pkg/syscall/exec_unix.go Thu Jun 19 10:20:01 2014 +1000
+++ b/src/pkg/syscall/exec_unix.go Wed Jul 30 14:03:39 2014 -0400
@@ -110,9 +110,11 @@
// Credential holds user and group identities to be assumed
// by a child process started by StartProcess.
type Credential struct {
- Uid uint32 // User ID.
- Gid uint32 // Group ID.
- Groups []uint32 // Supplementary group IDs.
+ Uid uint32 // User ID.
+ Gid uint32 // Group ID.
+ Groups []uint32 // Supplementary group IDs.
+ UidMappings string
+ GidMappings string
}
// ProcAttr holds attributes that will be applied to a new process started
@@ -188,13 +190,19 @@
}
// Kick off child.
- pid, err1 = forkAndExecInChild(argv0p, argvp, envvp, chroot, dir, attr, sys, p[1])
+ pid, err1 = forkAndExecInChild(argv0p, argvp, envvp, chroot, dir, attr, sys, p[1], p[0])
if err1 != 0 {
err = Errno(err1)
goto error
}
ForkLock.Unlock()
+ if sys.Credential != nil {
+ if err = writeUidGidMappings(pid, sys.Credential); err != nil {
+ goto error
+ }
+ }
+
// Read child error status from pipe.
Close(p[1])
n, err = readlen(p[0], (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1)))
@@ -259,3 +267,42 @@
uintptr(unsafe.Pointer(&envvp[0])))
return Errno(err1)
}
+
+func writeUidGidMappings(pid int, cred *Credential) error {
+ var (
+ uidf = "/proc/" + itoa(pid) + "/uid_map"
+ gidf = "/proc/" + itoa(pid) + "/gid_map"
+ )
+
+ if cred.UidMappings != "" {
+ fd, err := Open(uidf, O_RDWR, 0)
+ if err != nil {
+ return err
+ }
+
+ data := StringByteSlice(cred.UidMappings)
+ if _, err := Write(fd, data); err != nil {
+ Close(fd)
+ return err
+ }
+
+ Close(fd)
+ }
+
+ if cred.GidMappings != "" {
+ fd, err := Open(gidf, O_RDWR, 0)
+ if err != nil {
+ return err
+ }
+
+ data := StringByteSlice(cred.GidMappings)
+ if _, err := Write(fd, data); err != nil {
+ Close(fd)
+ return err
+ }
+
+ Close(fd)
+ }
+
+ return nil
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment