1

Depending on configuration, unprivileged (non-root) processes can create a user namespace.

RLIMIT_NPROC limits the number of processes per user.

If I enter a user namespace, can I create processes with different UIDs, and hence exceed my real RLIMIT_NPROC?

1

There's a general principle that having namespaces doesn't give you any additional privileges. There's nothing that you can do to the rest of the system with multiple namespaces that you couldn't do with a single namespace. What namespaces give you is the additional ability to apply additional restrictions to some of your processes.

RLIMIT_NPROC is the maximum number of processes you can create. If some of these processes are in namespaces, they may have fewer privileges, but they still count as one process. All of these processes are processes in the outer namespaces, anyway. They may have different UIDs inside the namespace, but outside the namespace, they're your processes.

  • Yep. There were 2 things confusing me about how this would work. 1) This resource is per-user (struct_user::processes field). Answer: since the RLIMIT value is still per-process, the namespaced process can't interfere with the RLIMIT of your "un-namespaced" processes. 2) If you had multiple UIDs inside a namespace, you would have access to multiple independent NPROC resources. Answer: you can't get multiple UIDs inside a namespace unless you can get multiple UIDs outside the namespace. LXC can do it using a privileged helper. stgraber.org/2014/01/17/lxc-1-0-unprivileged-containers – sourcejedi Feb 14 at 9:52
0

It doesn't seem so.

$ unshare -r
# ulimit -u 1000
# sh -c 'for i in $(seq 998); do sleep 1& done' >/dev/null
sh: fork: retry: Resource temporarily unavailable
sh: fork: retry: Resource temporarily unavailable
... (i.e. more than one error - so I guess my existing processes were already counted)
sh: fork: retry: Resource temporarily unavailable
-bash: fork: retry: Resource temporarily unavailable

Similarly:

$ unshare -r
# ulimit -u 1002
# sh -c 'for i in $(seq 100); do sleep 1& done' >/dev/null
# sleep 2
# for i in $(seq 10); do unshare -r sh -c 'for i in $(seq 100); do sleep 1& done' >/dev/null; done
sh: fork: retry: Resource temporarily unavailable
sh: fork: retry: Resource temporarily unavailable

Running ulimit -u 1000 inside unshare -r does not affect my user outside of the user namespace. Ah - this is because ulimit -u always sets a limit inside the process. But when the limit is checked in fork(), we compare the RLIMIT_NPROC for that process, against the total number of processes of the "real" UID, i.e. from the point of view of the "root" namespace.

So as far as I can see, this all works pretty nicely.


Incidentally, I notice you can't use user namespaces to create processes with multiple different UIDs, if you are not privileged.

$ unshare -r
# id -u
0
# setpriv --ruid 1 sh
setpriv: setresuid failed: Invalid argument

The rules for this aspect are explained e.g. by Michael Kerrisk in Namespaces in operation, part 5: User namespaces.

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.