Suppose I'm user ID 1000. I run a program inside a UID namespace, mapping UID 0 inside the namespace to UID 1000 outside the namespace. The program then attempts to change its own UID to 50, which doesn't have a corresponding UID outside the namespace. Does the program successfully change its own (kernel) UID? If so, what does its UID appear to be from outside the namespace? Is it still 1000, or is it something else? 
In a UID namespace, can I setuid to an unmapped UID?
linux kernel;namespace
I (finally) tested it in Fedora Rawhide. It looks like my initial impression is correct: if you run seteuid(50) inside a namespace, but uid 50 inside the namespace doesn't correspond to a uid outside the namespace, then the call to seteuid simply fails.In here, I'll use kernel uid to refer to a process's uid as seen by the kernel (and most processes outside of the user namespace), and subjective uid to refer to a process's uid as seen by itself (and other processes inside the namespace).Test 1First, let's see what happens when root calls seteuid(50). We open up Python, and see what its pid is:[fedora@ip-0-0-0-0 ~]$ sudo python                             Python 2.7.6 (default, Feb  4 2014, 15:36:52)                         [GCC 4.8.2 20140120 (Red Hat 4.8.2-14)] on linux2                     Type help, copyright, credits or license for more information.>>> import os                                                         >>> os.getpid()                                                       1081                                                                  In a second terminal, we can see that python's kernel uid is, in fact, 0 (root):[fedora@ip-0-0-0-0 ~]$ ls -ld /proc/1081dr-xr-xr-x. 9 root root 0 Feb  7 03:27 /proc/1081And the subjective uid is, of course, 0 as well:>>> os.geteuid()  0                 So now we change our uid to 50:>>> os.seteuid(50)In the second terminal, we see that the kernel uid has indeed changed to 50:[fedora@ip-0-0-0-0 ~]$ ls -ld /proc/1081dr-xr-xr-x. 9 50 root 0 Feb  7 03:27 /proc/1081Test 2Okay, now let's use unshare to create a new user namespace.[fedora@ip-0-0-0-0 ~]$ unshare --user python                   Python 2.7.6 (default, Feb  4 2014, 15:36:52)                         [GCC 4.8.2 20140120 (Red Hat 4.8.2-14)] on linux2                     Type help, copyright, credits or license for more information.>>> import os                                                         >>> os.getpid()                                                       1084                                                                  In the second terminal, we see that this process's kernel uid is 1000 (fedora):[fedora@ip-0-0-0-0 ~]$ ls -ld /proc/1084dr-xr-xr-x. 9 fedora fedora 0 Feb  7 03:30 /proc/1084But in the first terminal, we see that its subjective uid is 65534 (not mapped):>>> os.geteuid()65534           So, in the second terminal, we give python a mapping:[fedora@ip-0-0-0-0 ~]$ echo '0 1000 1' > /proc/1084/uid_mapIn the first terminal, we see that python's subjective uid is now 0:>>> os.geteuid()                     0                                    We try to set python's uid to 50, but this fails with Invalid argument (presumably EINVAL), because the subjective uid 50 has no mapping to a kernel uid:>>> os.seteuid(50)                   Traceback (most recent call last):     File <stdin>, line 1, in <module>OSError: [Errno 22] Invalid argument In the second terminal, we see that the process's kernel uid is unchanged:[fedora@ip-0-0-0-0 ~]$ ls -ld /proc/1084dr-xr-xr-x. 9 fedora fedora 0 Feb  7 03:30 /proc/1084And in the first terminal, we see that the process's subjective uid is unchanged, too:>>> os.geteuid()0               Test 3Okay, what happens if we define a mapping containing multiple uids? According to the LWN.net article Namespaces in operation, part 5: User namespaces, we need to run python after mapping the uids. (I tried this without mapping the uids before running python, and the seteuid operation gave Operation not permitted.) So first, we run a shell in a second new user namespace:[fedora@ip-0-0-0-0 ~]$ unshare --user  id: cannot find name for user ID 65534        id: cannot find name for group ID 65534       id: cannot find name for user ID 65534        [I have no name!@ip-10-239-133-144 ~]$ echo $$1798                                          Then, in the second terminal, we need to be root in order to define the mapping:[root@ip-10-239-133-144 fedora]# echo '0 1000 2' > /proc/1798/uid_mapAccording to the whoami command, our subjective uid is root now, so let's open up Python and set our subjective uid to 1:[I have no name!@ip-0-0-0-0 ~]$ whoami                         root                                                                  [I have no name!@ip-0-0-0-0 ~]$ python                         Python 2.7.6 (default, Feb  4 2014, 15:36:52)                         [GCC 4.8.2 20140120 (Red Hat 4.8.2-14)] on linux2                     Type help, copyright, credits or license for more information.>>> import os                                                         >>> os.seteuid(1)                                                     >>> os.getpid()                                                       1837                                                                  In the second terminal, we see that our kernel uid is now 1001, as expected:[root@ip-10-239-133-144 fedora]# ls -ld /proc/1837dr-xr-xr-x. 9 1001 fedora 0 Feb  7 04:00 /proc/1837Test 2 again?In test 3, we needed to define the mapping before running Python in order for the call to seteuid() to succeed. In test 2, we didn't do this. So, the obvious question is, if we did define the mapping before running Python, would the call to seteuid() work? It turns out that the answer is no. First terminal:[fedora@ip-0-0-0-0 ~]$ unshare --user  id: cannot find name for user ID 65534        id: cannot find name for group ID 65534       id: cannot find name for user ID 65534        [I have no name!@ip-0-0-0-0 ~]$ echo $$1861                                          Second terminal:[fedora@ip-0-0-0-0 ~]$ echo '0 1000 1' > /proc/1861/uid_mapFirst terminal:[I have no name!@ip-0-0-0-0 ~]$ whoami                         root                                                                  [I have no name!@ip-0-0-0-0 ~]$ python                         Python 2.7.6 (default, Feb  4 2014, 15:36:52)                         [GCC 4.8.2 20140120 (Red Hat 4.8.2-14)] on linux2                     Type help, copyright, credits or license for more information.>>> import os                                                         >>> os.geteuid()                                                      0                                                                     >>> os.seteuid(50)                                                    Traceback (most recent call last):                                      File <stdin>, line 1, in <module>                                 OSError: [Errno 22] Invalid argument                                  ConclusionIn order for a call to seteuid within a user namespace to succeed, the uid passed to seteuid must have a mapping outside the user namespace. Otherwise, the call will fail with EINVAL.