github.com/geofffranks/garden-linux@v0.0.0-20160715111146-26c893169cfa/containerizer/system/namespacing_execer_linux.go (about) 1 package system 2 3 import ( 4 "fmt" 5 "os" 6 "os/exec" 7 "syscall" 8 9 "github.com/cloudfoundry/gunk/command_runner" 10 ) 11 12 const UIDMappingRange = 65536 13 14 type NamespacingExecer struct { 15 CommandRunner command_runner.CommandRunner 16 ExtraFiles []*os.File 17 Privileged bool 18 19 // When User Namespaces are enabled, maps 1-MaxUID-1 UIDS, and 20 // maps container root (0) to MaxUID 21 MaxUID int 22 } 23 24 func (e *NamespacingExecer) Exec(binPath string, args ...string) (int, error) { 25 cmd := exec.Command(binPath, args...) 26 cmd.SysProcAttr = &syscall.SysProcAttr{} 27 28 flags := syscall.CLONE_NEWIPC 29 flags = flags | syscall.CLONE_NEWNET 30 flags = flags | syscall.CLONE_NEWNS 31 flags = flags | syscall.CLONE_NEWUTS 32 flags = flags | syscall.CLONE_NEWPID 33 34 if !e.Privileged { 35 flags = flags | syscall.CLONE_NEWUSER 36 37 mapping, err := makeSysProcIDMap(e.MaxUID) 38 if err != nil { 39 return 0, err 40 } 41 cmd.SysProcAttr.UidMappings = mapping 42 cmd.SysProcAttr.GidMappings = mapping 43 cmd.SysProcAttr.GidMappingsEnableSetgroups = true 44 45 cmd.SysProcAttr.Credential = &syscall.Credential{ 46 Uid: 0, 47 Gid: 0, 48 } 49 } 50 51 cmd.SysProcAttr.Cloneflags = uintptr(flags) 52 cmd.ExtraFiles = e.ExtraFiles 53 54 if err := e.CommandRunner.Start(cmd); err != nil { 55 return 0, fmt.Errorf("system: failed to start the supplied command: %s", err) 56 } 57 58 return cmd.Process.Pid, nil 59 } 60 61 func makeSysProcIDMap(maxUid int) ([]syscall.SysProcIDMap, error) { 62 return []syscall.SysProcIDMap{ 63 syscall.SysProcIDMap{ 64 ContainerID: 0, 65 HostID: maxUid, 66 Size: 1, 67 }, 68 syscall.SysProcIDMap{ 69 ContainerID: 1, 70 HostID: 1, 71 Size: maxUid - 1, 72 }, 73 }, nil 74 }