diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2020-01-10 22:22:37 +0100 |
---|---|---|
committer | Giuseppe Scrivano <gscrivan@redhat.com> | 2020-01-10 22:33:30 +0100 |
commit | 7a11ed5a77a631ea055dd09fbaca3111e5530085 (patch) | |
tree | 6874393642a12513453905c8b66119c55a04165f /pkg/util | |
parent | e1ffac6cc73eb36640cbaf6a1a28ba44749a96d9 (diff) | |
download | podman-7a11ed5a77a631ea055dd09fbaca3111e5530085.tar.gz podman-7a11ed5a77a631ea055dd09fbaca3111e5530085.tar.bz2 podman-7a11ed5a77a631ea055dd09fbaca3111e5530085.zip |
libpod: fix --userns=keep-id with big UIDs
when creating a keep-id namespace, we split the original user
namespace in:
inner ns | outer ns | size:
0 | 1 | ID
ID | 0 | 1
ID+1 | ID+1 | availableIds - ID
When the user ID is bigger than the number of available
subuids/subgids we fail to create the user namespace because the first
slice is bigger than the available number of IDs and the third one has
a negative size.
Fix it by not using more than the available number of IDs in the first
slice and creating the third one only if there are other IDs left.
When the user ID is bigger than the number of additional IDs, there
will be a gap between the two mappings so the IDs between the maximum
additional ID and the user ID won't be present inside of the
namespace.
Closes: https://github.com/containers/libpod/issues/4838
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'pkg/util')
-rw-r--r-- | pkg/util/utils.go | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/pkg/util/utils.go b/pkg/util/utils.go index c9d09b8b5..9269f6115 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -335,6 +335,13 @@ func ParseIDMapping(mode namespaces.UsernsMode, UIDMapSlice, GIDMapSlice []strin return nil, errors.New("cannot specify subuidmap or subgidmap with --userns=keep-id") } if rootless.IsRootless() { + min := func(a, b int) int { + if a < b { + return a + } + return b + } + uid := rootless.GetRootlessUID() gid := rootless.GetRootlessGID() @@ -352,13 +359,17 @@ func ParseIDMapping(mode namespaces.UsernsMode, UIDMapSlice, GIDMapSlice []strin options.UIDMap, options.GIDMap = nil, nil - options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: 0, HostID: 1, Size: uid}) + options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: 0, HostID: 1, Size: min(uid, maxUID)}) options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: uid, HostID: 0, Size: 1}) - options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: uid + 1, HostID: uid + 1, Size: maxUID - uid}) + if maxUID > uid { + options.UIDMap = append(options.UIDMap, idtools.IDMap{ContainerID: uid + 1, HostID: uid + 1, Size: maxUID - uid}) + } - options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: 0, HostID: 1, Size: gid}) + options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: 0, HostID: 1, Size: min(gid, maxGID)}) options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: gid, HostID: 0, Size: 1}) - options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: gid + 1, HostID: gid + 1, Size: maxGID - gid}) + if maxGID > gid { + options.GIDMap = append(options.GIDMap, idtools.IDMap{ContainerID: gid + 1, HostID: gid + 1, Size: maxGID - gid}) + } options.HostUIDMapping = false options.HostGIDMapping = false |