Christian Brauner d381a0d9d5 nsresourced: judge transient range writes by their real destination
nsresourced hands out transient, recyclable UID/GID ranges to
unprivileged user namespaces. So that a client cannot gain persistence by
leaving inodes owned by its transient range on a file system that outlives
the namespace -- where a later, unrelated client that recycles the range
would inherit them -- a BPF-LSM policy vetoes inode creation and chown()
that would end up owned by a transient ID.

The policy this replaces keyed its decision on properties of the mount a
write targeted. Those can be forged: a single unshare(CLONE_NEWNS) hands
the namespace clones of every mount it can see, each backed by the very
same superblock but no longer recognisable by the original check, and the
mount namespace's owning user namespace is attacker-chosen as well.

Decide instead from two questions about the object the write would actually
create, both answered from fields the kernel stamps itself and that survive
mount cloning and cannot be forged with unshare():

  a) Does the file system die with the user namespace? A superblock records
     the user namespace it was mounted in (sb->s_user_ns); if that sits at
     or below the managed namespace, nothing it carries can outlive the
     transient range.

  b) Will the transient ID actually reach the disk? An idmapped mount
     (vfsmount->mnt_idmap) may translate it into something else first, in
     which case nothing recyclable is recorded. This mirrors the kernel's
     own from_vfsuid()/from_vfsgid().

Walking the user-namespace chain upwards, rather than looking only at the
exact namespace, is what keeps a nested namespace from shaking off the
policy.

The map schema changed incompatibly (the old mount-id allowlist became the
flat userns_managed inode set), so the BPF objects are pinned under a fresh
directory, /sys/fs/bpf/systemd/userns-restrict-v2, and the obsolete
unsuffixed tree from previous versions is removed on install. Removing the
old link pins detaches the previous, bypassable programs, so they do not
linger attached next to the new ones.
2026-08-12 10:49:34 +02:00
…
2026-07-08 08:23:04 +02:00
2026-04-18 14:24:47 +01:00
…
…
2026-06-17 09:59:34 +00:00
2025-06-05 14:39:20 +02:00
2026-03-06 08:55:55 +01:00
2025-10-07 13:00:12 +01:00
…
2026-07-28 19:46:34 +09:00

Systemd

System and Service Manager

OBS Packages Status
Semaphore CI 2.0 Build Status
Coverity Scan Status
OSS-Fuzz Status
CIFuzz
CII Best Practices
Fossies codespell report
Translation status
Coverage Status
Packaging status
OpenSSF Scorecard

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

S
Description
systemd patched fork
Readme Cite this repository
409 MiB
Languages
C 88.5%
Shell 5.7%
Python 4.6%
Meson 1.1%