6

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?

Arks
  • 569
  • 5
  • 19
el_tigro
  • 1,099
  • 2
  • 10
  • 22

1 Answers1

16

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).

Arks
  • 569
  • 5
  • 19
  • Very complete and helpful answer! – el_tigro Feb 07 '18 at 15:49
  • 3
    `newuidmap: uid range [0-1) -> [0-1) not allowed` – L29Ah Dec 05 '19 at 15:11
  • Hello @L29Ah, it's been a long time so I can't remember the details at once, but it is something with settings in /etc/subuid and /etc/subguid files. You need to add correct ids for your users in their. – Arks Dec 05 '19 at 17:07
  • Just noting this is exactly what I was looking for and am super, super glad you took the time to write this out. – robbmanes Feb 04 '21 at 15:04
  • So, I don't get it, do you run the `newuidmap` in the same terminal or in another terminal? If in the same one, then why do you pass PID explicitly instead of `$$`; and also why is your prompt looks different *(`#` vs `$` in prev. output)*? FWIW, I can't check it because doing either way causes some distinct error for me *(which is either `newuidmap: uid range [0-1) -> [0-1) not allowed` or `newuidmap: Target process 83058 is owned by a different user`)*, and clarifying that would really help in figuring which one of errors shows a legit problem requiring an elaborate investigation. – Hi-Angel Mar 30 '21 at 14:00