Skip to content

Commit 814cfd4

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 526d3b3 commit 814cfd4

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
@@ -3,14 +3,7 @@
33

44
package userns
55

6-
import (
7-
"strings"
8-
9-
"github.com/opencontainers/runc/libcontainer/user"
10-
)
11-
12-
func FuzzUIDMap(data []byte) int {
13-
uidmap, _ := user.ParseIDMap(strings.NewReader(string(data)))
14-
_ = uidMapInUserNS(uidmap)
6+
func FuzzUIDMap(uidmap []byte) int {
7+
_ = uidMapInUserNS(string(uidmap))
158
return 1
169
}
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,
40+
// see 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
@@ -1,11 +1,6 @@
11
package userns
22

3-
import (
4-
"strings"
5-
"testing"
6-
7-
"github.com/opencontainers/runc/libcontainer/user"
8-
)
3+
import "testing"
94

105
func TestUIDMapInUserNS(t *testing.T) {
116
cases := []struct {
@@ -31,11 +26,7 @@ func TestUIDMapInUserNS(t *testing.T) {
3126
},
3227
}
3328
for _, c := range cases {
34-
uidmap, err := user.ParseIDMap(strings.NewReader(c.s))
35-
if err != nil {
36-
t.Fatal(err)
37-
}
38-
actual := uidMapInUserNS(uidmap)
29+
actual := uidMapInUserNS(c.s)
3930
if c.expected != actual {
4031
t.Fatalf("expected %v, got %v for %q", c.expected, actual, c.s)
4132
}

libcontainer/userns/userns_unsupported.go

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

44
package userns
55

6-
import "github.com/opencontainers/runc/libcontainer/user"
7-
86
// runningInUserNS is a stub for non-Linux systems
97
// Always returns false
108
func runningInUserNS() bool {
@@ -13,6 +11,6 @@ func runningInUserNS() bool {
1311

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

0 commit comments

Comments
 (0)