Skip to content

Commit faeea0e

Browse files
authored
Merge pull request #240 from aleivag/fix-userns-detection-proc-inode
userns: detect initial namespace by inode
2 parents d7c3b9e + 023b764 commit faeea0e

1 file changed

Lines changed: 18 additions & 0 deletions

File tree

userns/userns_linux.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff 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+
1014
var 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
1923
func 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.

0 commit comments

Comments
 (0)