Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion libcontainer/userns/userns.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
package userns

// RunningInUserNS detects whether we are currently running in a user namespace.
// Originally copied from github.com/lxc/lxd/shared/util.go
var RunningInUserNS = runningInUserNS
11 changes: 2 additions & 9 deletions libcontainer/userns/userns_fuzzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,7 @@

package userns

import (
"strings"

"github.com/opencontainers/runc/libcontainer/user"
)

func FuzzUIDMap(data []byte) int {
uidmap, _ := user.ParseIDMap(strings.NewReader(string(data)))
_ = uidMapInUserNS(uidmap)
func FuzzUIDMap(uidmap []byte) int {
_ = uidMapInUserNS(string(uidmap))
return 1
}
44 changes: 31 additions & 13 deletions libcontainer/userns/userns_linux.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package userns

import (
"bufio"
"fmt"
"os"
"sync"

"github.com/opencontainers/runc/libcontainer/user"
)

var (
Expand All @@ -12,26 +13,43 @@ var (
)

// runningInUserNS detects whether we are currently running in a user namespace.
// Originally copied from github.com/lxc/lxd/shared/util.go
//
// Originally copied from https://github.com/lxc/incus/blob/e45085dd42f826b3c8c3228e9733c0b6f998eafe/shared/util.go#L678-L700.
func runningInUserNS() bool {
nsOnce.Do(func() {
uidmap, err := user.CurrentProcessUIDMap()
file, err := os.Open("/proc/self/uid_map")
if err != nil {
// This kernel-provided file only exists if user namespaces are supported.
return
}
defer file.Close()

buf := bufio.NewReader(file)
l, _, err := buf.ReadLine()
if err != nil {
// This kernel-provided file only exists if user namespaces are supported
return
}
inUserNS = uidMapInUserNS(uidmap)

inUserNS = uidMapInUserNS(string(l))
})
return inUserNS
}

func uidMapInUserNS(uidmap []user.IDMap) bool {
/*
* We assume we are in the initial user namespace if we have a full
* range - 4294967295 uids starting at uid 0.
*/
if len(uidmap) == 1 && uidmap[0].ID == 0 && uidmap[0].ParentID == 0 && uidmap[0].Count == 4294967295 {
func uidMapInUserNS(uidMap string) bool {
if uidMap == "" {
// File exist but empty (the initial state when userns is created,
// see user_namespaces(7)).
return true
}

var a, b, c int64
if _, err := fmt.Sscanf(uidMap, "%d %d %d", &a, &b, &c); err != nil {
// Assume we are in a regular, non user namespace.
return false
}
return true

// As per user_namespaces(7), /proc/self/uid_map of
// the initial user namespace shows 0 0 4294967295.
initNS := a == 0 && b == 0 && c == 4294967295
return !initNS
}
13 changes: 2 additions & 11 deletions libcontainer/userns/userns_linux_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package userns

import (
"strings"
"testing"

"github.com/opencontainers/runc/libcontainer/user"
)
import "testing"

func TestUIDMapInUserNS(t *testing.T) {
cases := []struct {
Expand All @@ -31,11 +26,7 @@ func TestUIDMapInUserNS(t *testing.T) {
},
}
for _, c := range cases {
uidmap, err := user.ParseIDMap(strings.NewReader(c.s))
if err != nil {
t.Fatal(err)
}
actual := uidMapInUserNS(uidmap)
actual := uidMapInUserNS(c.s)
if c.expected != actual {
t.Fatalf("expected %v, got %v for %q", c.expected, actual, c.s)
}
Expand Down
4 changes: 1 addition & 3 deletions libcontainer/userns/userns_unsupported.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

package userns

import "github.com/opencontainers/runc/libcontainer/user"

// runningInUserNS is a stub for non-Linux systems
// Always returns false
func runningInUserNS() bool {
Expand All @@ -13,6 +11,6 @@ func runningInUserNS() bool {

// uidMapInUserNS is a stub for non-Linux systems
// Always returns false
func uidMapInUserNS(uidmap []user.IDMap) bool {
func uidMapInUserNS(uidMap string) bool {
return false
}