File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -5,8 +5,12 @@ import (
55 "fmt"
66 "os"
77 "sync"
8+ "syscall"
89)
910
11+ // See PROC_USER_INIT_INO in https://github.com/torvalds/linux/blob/v7.1/include/uapi/linux/nsfs.h#L50.
12+ const procUserInitIno = 0xEFFFFFFD
13+
1014var inUserNS = sync .OnceValue (runningInUserNS )
1115
1216// runningInUserNS detects whether we are currently running in a user namespace.
@@ -17,6 +21,20 @@ var inUserNS = sync.OnceValue(runningInUserNS)
1721// [libcontainer/runc]: https://github.com/opencontainers/runc/blob/3778ae603c706494fd1e2c2faf83b406e38d687d/libcontainer/userns/userns_linux.go#L12-L49
1822// [lcx/incus]: https://github.com/lxc/incus/blob/e45085dd42f826b3c8c3228e9733c0b6f998eafe/shared/util.go#L678-L700
1923func runningInUserNS () bool {
24+ var st syscall.Stat_t
25+ if err := syscall .Stat ("/proc/self/ns/user" , & st ); err == nil {
26+ return st .Ino != procUserInitIno
27+ } else if ! os .IsNotExist (err ) {
28+ // As long as /proc/self/ns/user exists, we are on a modern kernel.
29+ // Other errors indicate an unexpected procfs state, where assuming the
30+ // init namespace would be unsafe.
31+ return false
32+ }
33+
34+ // Only fall back for older kernels that do not expose the user namespace
35+ // through procfs at /proc/self/ns/user.
36+ // TODO: Remove this fallback once Linux kernels older than 3.8 are no
37+ // longer supported.
2038 file , err := os .Open ("/proc/self/uid_map" )
2139 if err != nil {
2240 // This kernel-provided file only exists if user namespaces are supported.
You can’t perform that action at this time.
0 commit comments