User namespaces: map identities without inventing host authority
Apply an explicit UID/GID range mapping and distinguish namespace-relative privilege from permissions on host resources and other kernel boundaries.
On this page
The question for today
What you’ll understand
- Translate IDs through a stated direct-parent mapping interval.
- Explain why namespace UID zero need not be initial-namespace UID zero.
- Identify unmapped IDs, group setup, mount ownership, and delegated-range assumptions.
A process can see itself as UID zero inside a user namespace while its parent namespace identifies it with an unprivileged ID. That mapping is powerful, but it is not a claim that all kernel operations or every host file are safely isolated. We use a direct child user namespace on Linux 6.12 with a single explicit interval so the arithmetic is visible. Real rootless runtime setup can use multiple ranges, helpers, nested namespaces, and idmapped mounts; each adds a translation or authorization rule that must be inspected.
A mapping is a partial interval translation
A mapping line specifies an inside start, an outside start, and a positive count. For a directly stated parent-relative interval, each inside ID in that interval maps to the corresponding outside offset. Outside the mapped ranges, the identity is not silently wrapped into another valid user. Kernel interfaces can reject operations or display an overflow identity according to their contracts. Read uid_map and gid_map in the relevant observing namespace, because the displayed outside relation can depend on who opens the mapping file.
Mapping setup is constrained by kernel permissions and is not an arbitrary write granting access to every host identity. Rootless tools commonly rely on authorized subordinate-ID ranges and privileged mapping helpers where needed. Group mapping has additional rules; unprivileged setups commonly must disable setgroups before writing the allowed gid_map under the kernel's permission conditions. This is a setup protocol to follow precisely, not a universal instruction to remove groups in every environment or proof that a single configuration works on every kernel.
Privilege is evaluated in an owning context
Capabilities are associated with user-namespace relationships and the namespaces that own the affected resources. Being privileged in a child user namespace does not mean possessing the corresponding capability in the initial namespace. A host file's ownership, mount mapping, ordinary permission bits, ACLs, and LSM policy still affect access. Likewise, sharing a network namespace or passing a privileged file descriptor can expose resources independently of the visible UID. Identity translation is one part of an access decision, not the entire decision.
A bind-mounted directory can therefore present surprising ownership without any kernel bug. A file owned by parent UID 100042 maps naturally to inside UID 42 under the example range, while a different parent ID may be unmapped. An idmapped mount can introduce another supported ownership interpretation at the mount boundary, which must not be confused with recursively changing file owners. Record both the process user namespace and the mount's actual mapping before applying chown as a speculative repair.
Validate the mapping and the access path separately
For a reproducible fixture, record the namespace identities, mapping files, effective credentials, file ownership, and mount attributes. Test access with the same UID, groups, capabilities, and inherited descriptors as the intended workload. A successful read as an administrator outside the container does not establish that the container should be able to read the same path. Conversely, a failed write may come from a read-only mount or LSM denial rather than the UID map. Change one mechanism at a time so the result has an interpretable cause.
The modular lab deliberately contrasts a cyclic map with UID translation. Reset, explicitly set modulus twelve and additive step five, predict the repeating residue orbit, then Play or Step. For another run Reset and explicitly set modulus twelve and step four. The first orbit has twelve residues and the second three. UID ranges do not follow either wraparound rule: an unmapped inside ID must not become an authorized outside ID by reducing it modulo a count. This arithmetic instrument contains no kernel credentials, mapping files, permissions, or namespace boundary.
Work it through
Translate a delegated interval exactly
Assume one valid direct-parent UID mapping with inside start zero, parent start 100000, and length 65536. Find the parent IDs for inside UID zero, 42, and 65535. Determine whether inside UID 65536 belongs to this extent.
The first inside ID zero maps to 100000+0=100000. Inside UID 42 maps to 100000+42=100042; neither is parent UID zero.
The last included inside ID is 65536−1=65535, mapping to 165535. The extent covers exactly 65536 IDs, including both of these endpoints.
Inside UID 65536 lies outside this single extent. It must be treated through the actual unmapped-ID behavior or a separate valid mapping extent, not wrapped to parent 100000. Access to a file additionally depends on the relevant filesystem and credential checks.
The mapping is one-to-one over its stated interval. The label root inside the namespace does not imply initial-namespace root authority.
The living notebook
Explore the model
Interactive lab · modular
Contrast cyclic residues with partial identity ranges
For independent runs choose Reset, explicitly set both m and additive step, predict, then Play or Step. Compare (12,5) with Reset plus (12,4): periods twelve and three. This cyclic addition model is not a UID mapping. Kernel ID extents do not wrap unmapped IDs into authorized identities.
- Residue r0
- 0
- Orbit period · m/gcd(m,a)
- 12
- Distinct residues visited
- 1 of 12
Addition modulo m starts at zero: rₙ = na mod m. Playback advances two additions per second. The orbit has period m/gcd(m,a), including period one for a = 0. This is not a cryptographic security test or a primality algorithm. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forIdentify the mathematical kind of a mapping before applying it: a partial authorized UID translation is not a modular residue orbit.
Pause & reason
Check your understanding
Your turn
Try it yourself
An extent maps inside IDs 100 through 199 to parent IDs beginning at 500000. What are the mapping count and the parent ID for inside 137? Would inside 200 wrap to the first parent ID?
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
The count includes both endpoints; translate by the offset from the inside start.
Compare with the solution
The extent length is 199−100+1=100. Inside 137 has offset 37 and maps to 500037. Inside 200 is outside this extent and does not wrap to 500000. A separate mapping or the relevant unmapped-ID behavior applies. For nested namespaces, compose the actual authorized mappings rather than calling this parent-relative result a host UID without checking the remaining levels. Even a correctly mapped identity must still pass the access controls on the resource it uses.
Keep the idea
Take it with you
- UID/GID extents define authorized partial translations, not cyclic arithmetic.
- Namespace root and initial-namespace root have different authority.
- Inspect process mappings, groups, mount mappings, and resource permissions together.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.