MCPcopy
hub / github.com/apptainer/apptainer / IsInsideUserNamespace

Function IsInsideUserNamespace

pkg/util/namespaces/user_linux.go:25–65  ·  view source on GitHub ↗

IsInsideUserNamespace checks if a process is already running in a user namespace and also returns if the process has permissions to use setgroups in this user namespace.

(pid int)

Source from the content-addressed store, hash-verified

23// user namespace and also returns if the process has permissions to use
24// setgroups in this user namespace.
25func IsInsideUserNamespace(pid int) (bool, bool) {
26 // default values returned in case of error
27 insideUserNs := false
28 setgroupsAllowed := false
29
30 // can fail if the kernel doesn't support user namespace
31 r, err := os.Open(fmt.Sprintf("/proc/%d/uid_map", pid))
32 if err != nil {
33 return insideUserNs, setgroupsAllowed
34 }
35 defer r.Close()
36
37 scanner := bufio.NewScanner(r)
38 // we are interested only by the first line of
39 // uid_map which would give us the answer quickly
40 // based on the value of size field
41 if scanner.Scan() {
42 fields := strings.Fields(scanner.Text())
43
44 // trust values returned by procfs
45 size, _ := strconv.ParseUint(fields[2], 10, 32)
46
47 // a size of 4294967295 means the process is running
48 // in the host user namespace
49 if uint32(size) == ^uint32(0) {
50 return insideUserNs, setgroupsAllowed
51 }
52
53 // process is running inside user namespace
54 insideUserNs = true
55
56 // should not fail if open call passed
57 d, err := os.ReadFile(fmt.Sprintf("/proc/%d/setgroups", pid))
58 if err != nil {
59 return insideUserNs, setgroupsAllowed
60 }
61 setgroupsAllowed = string(d) == "allow\n"
62 }
63
64 return insideUserNs, setgroupsAllowed
65}
66
67// HostUID attempts to find the original host UID if the current
68// process is root running inside a user namespace, and if not it

Callers 3

ExecMethod · 0.92
createFunction · 0.92
PrepareConfigMethod · 0.92

Calls 2

OpenMethod · 0.80
CloseMethod · 0.45

Tested by

no test coverage detected