Skip to content

Commit 6914ea0

Browse files
committed
libcontainer/userns: simplify, and separate from "user" package.
This makes libcontainer/userns self-dependent, largely returning to the original implementation from lxc. The `uiMapInUserNS` is kept as a separate function for unit-testing and fuzzing. Signed-off-by: Sebastiaan van Stijn <[email protected]>
1 parent 7362fa2 commit 6914ea0

File tree

4 files changed

+35
-36
lines changed

4 files changed

+35
-36
lines changed

libcontainer/userns/userns_fuzzer.go

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,7 @@
22

33
package userns
44

5-
import (
6-
"strings"
7-
8-
"github.com/opencontainers/runc/libcontainer/user"
9-
)
10-
11-
func FuzzUIDMap(data []byte) int {
12-
uidmap, _ := user.ParseIDMap(strings.NewReader(string(data)))
13-
_ = uidMapInUserNS(uidmap)
5+
func FuzzUIDMap(uidmap []byte) int {
6+
_ = uidMapInUserNS(string(uidmap))
147
return 1
158
}
Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package userns
22

33
import (
4+
"bufio"
5+
"fmt"
6+
"os"
47
"sync"
5-
6-
"github.com/opencontainers/runc/libcontainer/user"
78
)
89

910
var (
@@ -12,26 +13,42 @@ var (
1213
)
1314

1415
// runningInUserNS detects whether we are currently running in a user namespace.
15-
// Originally copied from github.com/lxc/lxd/shared/util.go
16+
// Originally copied from github.com/lxc/lxd/shared/util.go.
1617
func runningInUserNS() bool {
1718
nsOnce.Do(func() {
18-
uidmap, err := user.CurrentProcessUIDMap()
19+
file, err := os.Open("/proc/self/uid_map")
20+
if err != nil {
21+
// This kernel-provided file only exists if user namespaces are supported.
22+
return
23+
}
24+
defer file.Close()
25+
26+
buf := bufio.NewReader(file)
27+
l, _, err := buf.ReadLine()
1928
if err != nil {
20-
// This kernel-provided file only exists if user namespaces are supported
2129
return
2230
}
23-
inUserNS = uidMapInUserNS(uidmap)
31+
32+
inUserNS = uidMapInUserNS(string(l))
2433
})
2534
return inUserNS
2635
}
2736

28-
func uidMapInUserNS(uidmap []user.IDMap) bool {
29-
/*
30-
* We assume we are in the initial user namespace if we have a full
31-
* range - 4294967295 uids starting at uid 0.
32-
*/
33-
if len(uidmap) == 1 && uidmap[0].ID == 0 && uidmap[0].ParentID == 0 && uidmap[0].Count == 4294967295 {
37+
func uidMapInUserNS(uidMap string) bool {
38+
if uidMap == "" {
39+
// File exist but empty (the initial state when userns is created. see
40+
// user_namespaces(7)).
41+
return true
42+
}
43+
44+
var a, b, c int64
45+
if _, err := fmt.Sscanf(uidMap, "%d %d %d", &a, &b, &c); err != nil {
46+
// Assume we are in a regular, non user namespace.
3447
return false
3548
}
36-
return true
49+
50+
// As per user_namespaces(7), /proc/self/uid_map of
51+
// the initial user namespace shows 0 0 4294967295.
52+
initNS := a == 0 && b == 0 && c == 4294967295
53+
return !initNS
3754
}

libcontainer/userns/userns_linux_test.go

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,7 @@
22

33
package userns
44

5-
import (
6-
"strings"
7-
"testing"
8-
9-
"github.com/opencontainers/runc/libcontainer/user"
10-
)
5+
import "testing"
116

127
func TestUIDMapInUserNS(t *testing.T) {
138
cases := []struct {
@@ -33,11 +28,7 @@ func TestUIDMapInUserNS(t *testing.T) {
3328
},
3429
}
3530
for _, c := range cases {
36-
uidmap, err := user.ParseIDMap(strings.NewReader(c.s))
37-
if err != nil {
38-
t.Fatal(err)
39-
}
40-
actual := uidMapInUserNS(uidmap)
31+
actual := uidMapInUserNS(c.s)
4132
if c.expected != actual {
4233
t.Fatalf("expected %v, got %v for %q", c.expected, actual, c.s)
4334
}

libcontainer/userns/userns_unsupported.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
package userns
44

5-
import "github.com/opencontainers/runc/libcontainer/user"
6-
75
// runningInUserNS is a stub for non-Linux systems
86
// Always returns false
97
func runningInUserNS() bool {
@@ -12,6 +10,6 @@ func runningInUserNS() bool {
1210

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

0 commit comments

Comments
 (0)