Re: [PATCH 0/8] userns: per-namespace capability bounding set and opt-in netns loopback

From: Andy Lutomirski

Date: Thu Nov 05 2026 - 12:06:32 EST


On Thu, Nov 5, 2026 at 7:48 AM Hallgrimur H. Gunnarsson <halg@xxxxxxxxxx> wrote:
>
> On Tue, Nov 03, 2026 at 06:37:46AM -0600, Serge E. Hallyn wrote:
> > Generally, if I, or some users I support, need to use unprivileged containers
> > or user namespaces, then when an 0day comes along, I can hopefully trust them
> > not to exploit it. The biggest danger comes from the fact that, right now, if
> > they can use them, anyone can. So if someone can trigger some other code running
> > as user nginx or something, that can become a root vector.
> >
> > So what if we had a built-in feature or LSM which implemented a credential based
> > whitelist, entered at firstboot? Something like
> >
> > ```
> > # Default deny
> > uid == 1000 # approved
> > 1005 < uid < 1010 # approved
> > gid == 1005
> > security_label = lxc_user_t # Not sure how far we want to go with this
> > tty # must have a session
> > ```
> >
> > Now, if you want to use user namespaces for generic sandboxes for all
> > users, e.g. to confine browser activity or nginx modules, then this model
> > may not fit. Or rather, it might need a few tweaks.
>
> Thanks for taking a look and sharing the credential-based allowlist.
>
> The latter scenario (generic sandboxes for all users) is actually the
> primary use case that I'm targeting. I want to allow unprivileged users to
> create user namespaces, e.g. for sandboxing, but without granting them
> security-sensitive network capabilities (CAP_NET_ADMIN/CAP_NET_RAW) when
> they are not strictly needed, given the historically high risk of local
> privilege escalation associated with them.
>
> The two approaches target complementary layers of the problem. A credential
> allowlist at creation time controls who can create a user namespace, while
> this patch series controls what capabilities are available inside that
> namespace (and its descendants) once it is created.
>
> Gating creation works well when there is a clear boundary between trusted
> and untrusted users. However, in a multi-tenant environment (like a large
> container fleet), we generally treat workloads as untrusted by default.
> Because we still want to allow these untrusted workloads to use unprivileged
> user namespaces for sandboxing, it is essential to keep the attack surface
> small and follow the principle of least privilege whenever possible.
>
> More specifically, this patch series enables that model of safe sandboxing
> across three key use cases:
>
> 1. Configurable capability stripping: Administrators can enable unprivileged
> user namespaces for all users to support sandboxing, but configure the
> system to strip CAP_NET_ADMIN and CAP_NET_RAW by default in new user
> namespaces created by unprivileged users. Basic sandboxing rarely needs
> these (except to bring up loopback, which Patch 1 addresses via
> CLONE_NEWNET_LOOPBACK).
>
> The per-namespace bounding set can enforce this either globally via the
> sysctl, or explicitly via clone3() at the container manager level. This
> restriction is monotonic and persists down the namespace hierarchy.
>
> 2. Selectively granting CAP_NET_ADMIN: Some containerized workloads
> legitimately need CAP_NET_ADMIN to configure advanced networking for
> sub-containers. Because an unprivileged creator's child namespace is
> bounded by:
>
> parent_bset & (sysctl_ceiling | creator_effective)

Right after sending my last email, I had the following thought of a
variant of the model. Permission to gain CAP_NET_ADMIN via creating a
userns is kind of like a capability itself, right? We could get
pretty close to nice semantics if we allocated a capability bit for
this (CAP_USERNS_NET_ADMIN perhaps?) and, by default, giving it to all
users. Unfortunately, the latter part is tricky because even sticking
it in the ambient set won't keep it from being dropped by setuid.

Perhaps we could have an extra capability mask that is for default-on
capabilities.

The intuition for this is that permission to gain capabilities in a
userns is a mess if it's a sysctl (as sysctls are global and there is
no clean way to say that a particular unprivileged task may
nonetheless create namespaces with CAP_NET_ADMIN) and it's a mess if
it's a securebit (still has the latter problem), but it's much tidier
if it's tied to a task.