I'm brooding over the interactions between namespaces and
capabilities. Occasionally, I stumble over wording like the following
from user_namespaces
(7):
Holding CAP_SYS_ADMIN within the user namespace that owns a
process's mount namespace allows that process to ...
I do understand the following:
Every non-user namespace N is owned by a user namespace U, which is determined by the process creating N being in U at that time.
Capabilities are a property of a process (more accurately: thread) or a file. For this discussion, I think it's good enough to think about processes for now.
For every type of namespace, every process is in exactly one namespace of that type.
Exactly the PID namespaces and the user namespaces form hierarchies. My understanding of the wording in the docs is, that even if a process P is in a namespace A, which in turn is a child of namespace B, one would still not say that P is in B, because P is in A and it is in only one namespace of that type. In other words: The parental relationship of namespaces must not be confused with set inclusion.
Now, the wording
Holding a capability within the user namespace U that owns a
process's mount namespace M allows that process P to ...
tells me to go from a process P to its mount namespace M
(/proc/P/ns/mnt), figure out its owning user namespace U
(ioctl_ns
(2)) and then verify if the process holds a capability in U.
It's the last part I don't get: P is not necessarily in U, so how can it hold a capability there? Is there a Process × Usernamespace ↦ Capabilities mapping? Also, U is associated with a UID, but capabilities are not a property of user IDs.