|
|
Log in / Subscribe / Register

Variant for chroot ?

Variant for chroot ?

Posted Mar 13, 2026 4:34 UTC (Fri) by wtarreau (subscriber, #51152)
Parent article: Practical uses for a null filesystem

What I'd like to see would be a variant of chroot() which would automatically create such a nullfs, enter it and lazy-unmount it so that once the caller dies, it's automatically unmounted. It would allow to completely isolate the caller. I'm using chroot() to empty directories with no permissions as an isolation for daemons and it works reasonably well because you cannot easily escape it (nowhere to mkdir+chroot+cd again). Of course the daemon must not hold any FD pointing to an external directory! In this case we could imagine something like this:

#define NULLFS_DIR (const char *)1
chroot(NULLFS_DIR); // mount nullfs and mark it lazy-umount (will it work before chdir()?)
chdir("/");


to post comments

Variant for chroot ?

Posted Mar 13, 2026 5:25 UTC (Fri) by tamiko (subscriber, #115350) [Link] (2 responses)

It sounds like you're looking for the $ unshare helper program. Unsharing the current mount namespace and putting a child process into it has exactly the semantics you're looking for: when the child exits the namespace is removed as well.

The new nullfs mount has the advantage that you can start with a truly empty mount namespace instead of mounting over and sealing. That's at least my current understanding.

But out of curiosity: do you know "bubblewrap"? It is a fantastic helper tool to createnlightweight sandboxes via namespaces. Best of all, you can run it as an unprivileged user. And it can do all of the sandboxing you're talking about.

Variant for chroot ?

Posted Mar 13, 2026 9:42 UTC (Fri) by wtarreau (subscriber, #51152) [Link] (1 responses)

> It sounds like you're looking for the $ unshare helper program. Unsharing the current mount namespace and putting a child process into it has exactly the semantics you're looking for: when the child exits the namespace is removed as well.

I'm already using it for other stuff, and could indeed call unshare(CLONE_FS) in the program. But I seem to remember that abstract unix socket paths are affected by unshare(CLONE_FS). This could be an acceptable tradeoff for most use cases though.

> But out of curiosity: do you know "bubblewrap"?

No I don't.

> It is a fantastic helper tool to createnlightweight sandboxes via namespaces. Best of all, you can run it as an unprivileged user. And it can do all of the sandboxing you're talking about.

I'm really talking about doing the sandboxing from within the deamon itself. Normally my programs boot, parse config files, load libraries etc, then chroot(), chdir() and drop privileges. Here I could indeed do unshare() instead of the first two steps and it would also work for unprivileged users, but maybe with an abns limitation that I'd need to recheck. Thanks for raising this hint I had just forgotten about!

Variant for chroot ?

Posted Mar 13, 2026 13:57 UTC (Fri) by qyliss (subscriber, #131684) [Link]

> But I seem to remember that abstract unix socket paths are affected by unshare(CLONE_FS). This could be an acceptable tradeoff for most use cases though.

According to network_namespaces(7), those are scoped to network namespace.

Variant for chroot ?

Posted Mar 14, 2026 1:35 UTC (Sat) by geofft (subscriber, #59789) [Link] (1 responses)

> enter it and lazy-unmount it so that once the caller dies, it's automatically unmounted

This is already the behavior of, say, a tmpfs in a mount namespace. It's reference-counted and once the last process referencing it dies, the tmpfs is cleaned up. You can see this very clearly by creating a large file and looking at memory usage before/after a kill -9 of the owning process.

Mostly for amusement purposes, I wrote a mkdtemp() alternative that works by creating a child process in a new unprivileged user+mount namespace and having it pass back a handle to a tmpfs. https://ldpreload.com/p/verytmp.c

A friend ported it to Rust and has a slightly more detailed writeup: https://blinsay.com/posts/verytmp/

(nullfs appears to not be mountable inside a userns, largely because it's a global singleton. So you don't actually need to garbage-collect it, but I guess this also means you might not be a way to actually get to it from a regular userspace process.)

Variant for chroot ?

Posted Mar 16, 2026 9:24 UTC (Mon) by taladar (subscriber, #68407) [Link]

At first I thought mounting nullfs might be safer to allow for a user than most other filesystems since it can not replace the content it is mounted over, just hide it, but I guess there is the edge case of config.d style directories where you could cut out some parts of the configuration for some setuid root tool like sudo that way.


Copyright © 2026, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds