Thread (39 messages) 39 messages, 9 authors, 5d ago

Re: [RFC] Null Namespaces

From: Jann Horn <jannh@google.com>
Date: 2026-07-06 16:32:56
Also in: linux-arch, linux-fsdevel, lkml

On Mon, Jul 6, 2026 at 4:52 PM Christian Brauner [off-list ref] wrote:
I think the straightforward solution to FD_NULLFS_ROOT would be to just:

- make it always available
- refer to the caller's mount namespace nullfs
- work with fchroot()/fchdir()

So I considered two chroot() use-cases for the sake of simplicity:

(1) You want to isolate yourself for the sake of lookup

(2) You want to isolate yourself to assemble a "private mount tree" but
    not really be in a separate namespace (very odd use-case... but it
    helps to make a point).

The problem with this approach is that everyone who chroots into the
nullfs root would suffer from the problem that any mount on top of it is
still visible. So that kinda makes it pointless for both (1) and (2).

Also all mounts that someone else would do would also be visible
allowing multiple chroot()ers to affect each others state. That also
would somewhat defeat the purpose of the chroot(). So I'm not convinced
this is what we should do.

IOW, I think FD_NULLFS_ROOT to chroot to the nullfs of your mount
namespace is mostly useless and just not workable for unprivileged
fchroot().

Instead, this made me consider whether it wouldn't make more sense to
allow unprivileged mount namespace unsharing for both CLONE_EMPTY_MNTNS
and UNSHARE_EMPTY_MNTNS. Look, there's no real risk at all. It is
literally just placing the caller into a new mount namespace with only
nullfs in there. I fail to see any attack vector here. It's literally
self-sandboxing and you give up access to anything that you didn't have
a file descriptor open for. It's actually a bonus, because you don't
need to use userns for this. You just throw away your filesystem state.
I mostly agree, though we might want to gate this on no_new_privs just
to be sure - you could theoretically have a setuid root program that
gives the caller more privileges if it can't find its config file.
That's kind of a far-fetched scenario, and in reality it would
probably fail because the dynamic linker can't be found, but there is
precedent for other sandboxing stuff also requiring no_new_privs, so
we might as well require that here, too...

(I think it actually might be fine to just make chroot entirely
unprivileged as long as no_new_privs is set, but I don't think we
should actually do that, that would just be unnecessarily playing with
fire and would probably confuse some security monitoring tools or
such.)

We should probably also reject if current_chrooted() is true, for the
same reason we reject userns creation when that's true.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help