mirror of
https://github.com/criyle/go-sandbox.git
synced 2025-11-04 14:49:53 +08:00
68 lines
1.6 KiB
Go
68 lines
1.6 KiB
Go
package forkexec
|
|
|
|
import (
|
|
"strconv"
|
|
"syscall"
|
|
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
// writeUidGidMappings writes User ID and Group ID mappings for user namespaces
|
|
// for a process and it is called from the parent process.
|
|
func writeIDMaps(r *Runner, pid int) error {
|
|
var uidMappings, gidMappings, setGroups []byte
|
|
pidStr := strconv.Itoa(pid)
|
|
|
|
if r.UIDMappings == nil {
|
|
uidMappings = []byte("0 " + strconv.Itoa(unix.Geteuid()) + " 1")
|
|
} else {
|
|
uidMappings = formatIDMappings(r.UIDMappings)
|
|
}
|
|
if err := writeFile("/proc/"+pidStr+"/uid_map", uidMappings); err != nil {
|
|
return err
|
|
}
|
|
|
|
if r.GIDMappings == nil || !r.GIDMappingsEnableSetgroups {
|
|
setGroups = setGIDDeny
|
|
} else {
|
|
setGroups = setGIDAllow
|
|
}
|
|
if err := writeFile("/proc/"+pidStr+"/setgroups", setGroups); err != nil {
|
|
return err
|
|
}
|
|
|
|
if r.GIDMappings == nil {
|
|
gidMappings = []byte("0 " + strconv.Itoa(unix.Getegid()) + " 1")
|
|
} else {
|
|
gidMappings = formatIDMappings(r.GIDMappings)
|
|
}
|
|
if err := writeFile("/proc/"+pidStr+"/gid_map", gidMappings); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func formatIDMappings(idMap []syscall.SysProcIDMap) []byte {
|
|
var data []byte
|
|
for _, im := range idMap {
|
|
data = append(data, []byte(strconv.Itoa(im.ContainerID)+" "+strconv.Itoa(im.HostID)+" "+strconv.Itoa(im.Size)+"\n")...)
|
|
}
|
|
return data
|
|
}
|
|
|
|
// writeFile writes file
|
|
func writeFile(path string, content []byte) error {
|
|
fd, err := unix.Open(path, unix.O_RDWR|unix.O_CLOEXEC, 0)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if _, err := unix.Write(fd, content); err != nil {
|
|
unix.Close(fd)
|
|
return err
|
|
}
|
|
if err := unix.Close(fd); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|