2

I think that usually a normal user is not allowed to give away a file or directory by running chown without sudo. A question was asked and answered at unix.stackexchange:Why can't a normal user chown a file?. I understood why it was designed like that.

Recently I started to play with rootless Podman. Then I learned that, for example, I could run

podman unshare chown -R 1111:1111 folder/

to change the ownership of the folder folder to another user/group (in the above example, it will be 101110:101110 by default on the host).

In some sense, it breaks the previously mentioned restriction. Why is this allowed? Will it cause some potential security issue? (Probably should the root user be careful with the /etc/subid when allocating the namespace?)

I am a just an amateur and I run everything on my own laptop. So I do not need to worry too much about this though. However, I would like to ask this question just for curiosity.

1

TL;DR: rootless podman requires newuidmap and newgidmap which are setuid root binaries, allowing to bootstrap operations for the rootless container.

To answer the question asked:

All the uid:gid values that can be created by the use of a rootless container were already reserved for a given user in the first place. They were not given away, because those additional uid:gid values can easily be associated back to a single original user, by checking the (never overlapping) contents of /etc/subuid and /etc/subgid.

Long example with explanations to follow.


Here are the low level tools to do the same command as OP, available on every standard Linux system (such as Debian, RHEL (>= 7.7), etc.):

terminal1:

user@host$ stat -c '%u:%g %n' folder/a folder
1000:1000 folder/a
1000:1000 folder
user@host$ chown -R 1111:1111 folder/
chown: changing ownership of 'folder/a': Operation not permitted
chown: changing ownership of 'folder/': Operation not permitted
user@host$ id -u; id -g
1000
1000
user@host$ unshare -U
nobody@host$ echo $$
11893
nobody@host$ id -u; id -g
65534
65534
nobody@host$ chown -R 1111:1111 folder/
chown: changing ownership of 'folder/a': Invalid argument
chown: changing ownership of 'folder/': Invalid argument

Note that the error isn't even the same right now (see later).

terminal2:

user@host$ grep ^user: /etc/subuid /etc/subgid
/etc/subuid:user:1410720:65536
/etc/subgid:user:1410720:65536
user@host$ newuidmap 11893 0 1000 1 1 1410721 65535
user@host$ newgidmap 11893 0 1000 1 1 1410721 65535

The commands above mapped the user's real id and gid (which are valid in addition of the subids and subgids) as root in its freshly created user namespace (whose sole member is the shell process (and the commands run from it)), and mapped (almost) the whole allocated range of subid and subgid to it too. As it can be done only once for uid and once for gid, it must be done one-shot.

again on terminal1:

nobody@host$ id -u; id -g; exec bash
0
0
root@host# 
root@host# chown -v -R 1111:1111 folder/
changed ownership of 'folder/a' from root:root to 1111:1111
changed ownership of 'folder/' from root:root to 1111:1111

on terminal2:

user@host$ stat -c '%u:%g %n' folder/a folder
1411831:1411831 folder/a
1411831:1411831 folder

Where we have 1411831-1111=1410720

For OP's case, considering 101110-1111=99999 it's more likely, that podman did map the first subuid too (as 1) giving rather 101110-1111+1=100000, so 100000 is the likely value in /etc/subuid and /etc/subgid for the given user. Anyway you get the idea.

Why did this work? That's simple: newuidmap and newgidmap are setuid root commands, or at least have enough capabilities to be able to work properly. They are helper tools allowing a normal user creating a simple user namespace to use its allocated mappings provided in /etc/subuid and /etc/subgid when the account was initially created.

user@host$ stat -c %A /usr/bin/newuidmap /usr/bin/newgidmap
-rwsr-xr-x
-rwsr-xr-x

Now the whole range of uid:gid mapped from host into the user namespace, is available for normal operations in this user namespace. So inside this user namespace, its root user can change the value from anything within range to anything else within range. Most often the range is a slice of 65536 entries (or probably for podman 1+65536=65537), but the host has a range of 2^32-1 available for this. Not the user namespace:

terminal1:

root@host# chown 66000 folder
chown: changing ownership of 'folder': Invalid argument

Not mapped, that was the case for the previous similar errors when mappings weren't done at all.

Note that as stated in troubleshooting, rootless podman does use newuidmap and newgidmap:

9) Newuidmap missing when running rootless Podman commands

Rootless Podman requires the newuidmap and newgidmap programs to be installed.

More inner workings of uid mapping can be found in the user namespaces manpage.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.