nsresourced hands out transient, recyclable UID/GID ranges to unprivileged user namespaces, and a BPF-LSM policy is what keeps a client from leaving inodes owned by its transient range on a file system that outlives the namespace, so that a later client which gets the same range can't inherit them. The old policy decided based on the mount a write went through, which is forgeable: unshare(CLONE_NEWNS) gives you clones of every mount with fresh mount IDs but the same superblock, and the mount namespace's owner is yours to pick. overlayfs sidesteps it entirely. So this reworks the check to look at where the write actually lands on disk. The first commit (Christian Brauner's) replaces the per-mount allowlist with two questions answered from fields the client can't forge and that survive mount cloning: does the file system die together with the user namespace (sb->s_user_ns at or below the managed one), and does the transient ID actually reach the disk, or does an idmapped mount translate it into something else first. It walks the userns chain upwards so a nested namespace can't escape it. The map layout changed, so the pins move to userns-restrict.v2 and the old ones are removed on install. The second commit handles overlayfs. A write through an overlay creates the file on the upper layer via vfs_create(), which only trips the inode LSM hooks, not the path hooks we attach to, and the one path hook that does fire sees the overlay mount, which belongs to the managed namespace and so looks like it dies with it even though the upper may be persistent. So we judge the upper at mount time in sb_kern_mount and refuse a writable overlay unless its upper dies with the namespace too. Reading overlayfs' private ovl_fs/ovl_layer uses CO-RE type flavors guarded by bpf_core_type_exists(), and the service now orders after modprobe@overlay.service. The third commit deals with restarts. The managed set only lives in the pinned maps, so an upgrade that changes the map layout comes up with empty maps and every already-running namespace silently loses its restriction. manager_startup() now re-adds the live registry entries to the maps in the same pass that reaps the dead ones. The setgroups() denial is restored from a flag we now store in the registry. One consequence: a managed namespace can only mount a writable overlay whose upper dies with it, e.g. a tmpfs it set up itself. If you need a writable persistent upperdir (mkosi does), use a plain unprivileged user namespace for that, not a transient nsresourced range.
System and Service Manager
Details
Most documentation is available on systemd's website.
Assorted, older, general information about systemd can be found in the systemd Wiki.
Information about build requirements is provided in the README file.
Consult our NEWS file for information about what's new in the most recent systemd versions.
Please see the Code Map for information about this repository's layout and content.
Please see the Hacking guide for information on how to hack on systemd and test your modifications.
Please see our Contribution Guidelines for more information about filing GitHub Issues and posting GitHub Pull Requests.
When preparing patches for systemd, please follow our Coding Style Guidelines.
If you are looking for support, please contact our mailing list, join our IRC channel #systemd on libera.chat or Matrix channel
Stable branches with backported patches are available in the stable repo.
We have a security bug bounty program sponsored by the Sovereign Tech Fund hosted on YesWeHack
Repositories with distribution packages built from git main are available on OBS, and also repositories with packages built from the latest stable release
