diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2020-12-23 14:21:28 +0100 |
---|---|---|
committer | Giuseppe Scrivano <gscrivan@redhat.com> | 2021-01-07 09:42:27 +0100 |
commit | ecedda63a6488162c9aad2a99c1ada172340ac7f (patch) | |
tree | 06b5d2d9810a769b1b67e05ad3559666a191721f /pkg/rootless/rootless_test.go | |
parent | 09f4cc6fc3d431c67b8f035b3ba25de9d3ec5496 (diff) | |
download | podman-ecedda63a6488162c9aad2a99c1ada172340ac7f.tar.gz podman-ecedda63a6488162c9aad2a99c1ada172340ac7f.tar.bz2 podman-ecedda63a6488162c9aad2a99c1ada172340ac7f.zip |
rootless: automatically split userns ranges
writing to the id map fails when an extent overlaps multiple mappings
in the parent user namespace:
$ cat /proc/self/uid_map
0 1000 1
1 100000 65536
$ unshare -U sleep 100 &
[1] 1029703
$ printf "0 0 100\n" | tee /proc/$!/uid_map
0 0 100
tee: /proc/1029703/uid_map: Operation not permitted
This limitation is particularly annoying when working with rootless
containers as each container runs in the rootless user namespace, so a
command like:
$ podman run --uidmap 0:0:2 --rm fedora echo hi
Error: writing file `/proc/664087/gid_map`: Operation not permitted: OCI permission denied
would fail since the specified mapping overlaps the first
mapping (where the user id is mapped to root) and the second extent
with the additional IDs available.
Detect such cases and automatically split the specified mapping with
the equivalent of:
$ podman run --uidmap 0:0:1 --uidmap 1:1:1 --rm fedora echo hi
hi
A fix has already been proposed for the kernel[1], but even if it
accepted it will take time until it is available in a released kernel,
so fix it also in pkg/rootless.
[1] https://lkml.kernel.org/lkml/20201203150252.1229077-1-gscrivan@redhat.com/
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'pkg/rootless/rootless_test.go')
-rw-r--r-- | pkg/rootless/rootless_test.go | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/pkg/rootless/rootless_test.go b/pkg/rootless/rootless_test.go new file mode 100644 index 000000000..ef574099c --- /dev/null +++ b/pkg/rootless/rootless_test.go @@ -0,0 +1,101 @@ +package rootless + +import ( + "reflect" + "testing" + + "github.com/opencontainers/runc/libcontainer/user" + spec "github.com/opencontainers/runtime-spec/specs-go" +) + +func TestMaybeSplitMappings(t *testing.T) { + mappings := []spec.LinuxIDMapping{ + { + ContainerID: 0, + HostID: 0, + Size: 2, + }, + } + desiredMappings := []spec.LinuxIDMapping{ + { + ContainerID: 0, + HostID: 0, + Size: 1, + }, + { + ContainerID: 1, + HostID: 1, + Size: 1, + }, + } + availableMappings := []user.IDMap{ + { + ID: 1, + ParentID: 1000000, + Count: 65536, + }, + { + ID: 0, + ParentID: 1000, + Count: 1, + }, + } + newMappings := MaybeSplitMappings(mappings, availableMappings) + if !reflect.DeepEqual(newMappings, desiredMappings) { + t.Fatal("wrong mappings generated") + } + + mappings = []spec.LinuxIDMapping{ + { + ContainerID: 0, + HostID: 0, + Size: 2, + }, + } + desiredMappings = []spec.LinuxIDMapping{ + { + ContainerID: 0, + HostID: 0, + Size: 2, + }, + } + availableMappings = []user.IDMap{ + { + ID: 0, + ParentID: 1000000, + Count: 65536, + }, + } + newMappings = MaybeSplitMappings(mappings, availableMappings) + + if !reflect.DeepEqual(newMappings, desiredMappings) { + t.Fatal("wrong mappings generated") + } + + mappings = []spec.LinuxIDMapping{ + { + ContainerID: 0, + HostID: 0, + Size: 1, + }, + } + desiredMappings = []spec.LinuxIDMapping{ + { + ContainerID: 0, + HostID: 0, + Size: 1, + }, + } + availableMappings = []user.IDMap{ + { + ID: 10000, + ParentID: 10000, + Count: 65536, + }, + } + + newMappings = MaybeSplitMappings(mappings, availableMappings) + if !reflect.DeepEqual(newMappings, desiredMappings) { + t.Fatal("wrong mappings generated") + } +} |