nsresourced: Optionally map foreign UID range

Whenever delegating UID ranges to a user namespace, it can also be
useful to map the foreign UID range, so that the container running in
the user namespace with delegated UID ranges can download container
images and unpack them to the foreign UID range.

Let's add an option mapForeign to make this possible. Note that this option
gives unprivileged users full access to the any foreign UID range owned directory
that they can access. Hence it is recommended (and already was recommended) to
store foreign UID range owned directories in a 0700 directory owned by the
owner of the tree to avoid access and modifications by other users.

This is already the case for the main users of the foreign UID range,
namely /var/lib/machines, /var/lib/portables and /home/<user> which all
use 0700 as their mode.

Users will also be able to create foreign UID range owned inodes in any
directories their own user can write to (on most systems this means /tmp,
/var/tmp and /home/<user>).
This commit is contained in:
Daan De Meyer
2026-02-24 18:29:37 +01:00
committed by Daan De Meyer
parent 95d05079bf
commit 838528104b
6 changed files with 73 additions and 5 deletions
+18
View File
@@ -99,6 +99,24 @@ test "$(run0 -u testuser --pipe unshare --user varlinkctl --exec call \
'{"name":"test-delegate3","size":65536,"userNamespaceFileDescriptor":0,"delegateContainerRanges":2}' \
-- cat /proc/self/uid_map | wc -l)" -eq 3
# Test mapForeign parameter
# Verify that the foreign UID range is mapped into the user namespace
# When mapForeign is true, uid_map should have 2 lines: primary range + foreign range
test "$(run0 -u testuser --pipe unshare --user varlinkctl --exec call \
--push-fd=/proc/self/ns/user \
/run/systemd/userdb/io.systemd.NamespaceResource \
io.systemd.NamespaceResource.AllocateUserRange \
'{"name":"test-foreign","size":65536,"userNamespaceFileDescriptor":0,"mapForeign":true}' \
-- cat /proc/self/uid_map | wc -l)" -eq 2
# Verify the foreign range is mapped 1:1.
test "$(run0 -u testuser --pipe unshare --user varlinkctl --exec call \
--push-fd=/proc/self/ns/user \
/run/systemd/userdb/io.systemd.NamespaceResource \
io.systemd.NamespaceResource.AllocateUserRange \
'{"name":"test-foreign2","size":65536,"userNamespaceFileDescriptor":0,"mapForeign":true}' \
-- cat /proc/self/uid_map | grep -c 2147352576)" -eq 1
# This should work without the key
systemd-dissect --image-policy='root=verity:=absent+unused' --mtree /var/tmp/unpriv.raw >/dev/null
systemd-dissect --image-policy='root=verity+signed:=absent+unused' --mtree /var/tmp/unpriv.raw >/dev/null