unshare user namespace and set uid mapping with newuidmap

12.6k views Asked by At

I'm trying to gain a better understanding of user namespaces by experimenting with the unshare and newuidmap commands.

These are the commands I ran:

[root@host ~]$ ls -l /usr/bin/newuidmap
-rwsr-xr-x 1 root root 32944 May 16 19:37 /usr/bin/newuidmap
[root@host ~]$  unshare -U bash namespace
[nobody@host ~]$ echo $$
7134
[nobody@host ~]$ newuidmap 7134 65534 5000 1
newuidmap: write to uid_map failed: Operation not permitted

/etc/subuid:

nobody:5000:1
root:5000:1

Any idea why this is failing?

I then tried to run the newuidmap command on the same PID from the parent namespace and it appeared to work:

[root@host ~]$ newuidmap 7134 65534 5000 1
[root@host ~]$ cat /proc/7134/uid_map 
 65534       5000          1

But when I run a process from within the new namespace it still seems to run as root instead of UID 5000:

[nobody@host ~]$ exec sleep 20

From another shell:

[root@host ~]$ ps aux | grep 7134
root      7134  0.0  0.0   7292   708 pts/2    S+   02:07   0:00 sleep 20

What am I missing?

1

There are 1 answers

5
Arks On BEST ANSWER

catanman

1)

[nobody@host ~]$ newuidmap 7134 65534 5000 1
newuidmap: write to uid_map failed: Operation not permitted

Any idea why this is failing?

Documentation (http://man7.org/linux/man-pages/man7/user_namespaces.7.html) states the following:

The child process created by clone(2) with the CLONE_NEWUSER flag starts out with a complete set of capabilities in the new user namespace. <...> Note that a call to execve(2) will cause a process's capabilities to be recalculated in the usual way (see capabilities(7)).

This happens because unshare calls 'exec bash' before returing the control to the user and you loose the necessary capabilities, thus you cannot change uid_map/gid_map from within user namespace.

Still, if you compile some application (e.g. you can make a small fix in an example from user_namespaces(7)) which updates uid_map/gid_map before 'exec', the update will succeed.

2)

But when I run a process from within the new namespace it still seems to run as root instead of UID 5000:

What am I missing?

  • The mapping does not change the user. The mapping links ids in a child namespace to ids in its parent namespace, not the opposite way.
  • You can call setuid(2) or seteuid(2) from within a child namespace to change the credentials to some other credentials from the same user namespace. They of course should be mapped onto the values in the parent namespace, otherwise geteuid() function will fail.

Here are two examples:

Example 1. Suppose we have created a child user namespace.

arksnote linux-namespaces   # unshare -U bash
nobody@arksnote ~  $ id
uid=65534(nobody) gid=65534(nobody) группы=65534(nobody)
nobody@arksnote ~  $ echo $$
18526

Now let's link root from parent namespace with some id (0 in this case) in a child namespace:

arksnote linux-namespaces   # newuidmap 18526 0 0 1
arksnote linux-namespaces   # cat /proc/18526/uid_map
         0          0          1

Here's what happens to the child namespace:

nobody@arksnote ~  $ id
uid=0(root) gid=65534(nobody) группы=65534(nobody)

You can try some other mappings, like newuidmap 18526 1 0 1 and see that it is applied to the child user namespace, not the parent one.

Example 2: Now we does not set a mapping for root:

arksnote linux-namespaces   # newuidmap 18868 0  1000 1
arksnote linux-namespaces   # cat /proc/18868/uid_map
         0       1000          1

In this case the user root is left unknown for the child user namespace:

nobody@arksnote ~  $ id
uid=65534(nobody) gid=65534(nobody) группы=65534(nobody)

What you have done with [root@host ~]$ newuidmap 7134 65534 5000 1 was association of userid 5000 in a parent namespace with uid 65534 in a child namespace, but the process still runs as root. It is shown as 65534 only because this value is used for any unknown id:

Functions getuid(), getgid() returns the value from /proc/sys/kernel/overflowgid for uids/gids which does not have a mapping. The value corresponds to a special user without any system rights:nobody, as you can see in uid/gid in the output above.

See Unmapped user and group IDs in user_namespaces(7).