Hacker News new | ask | show | jobs
by tedunangst 3879 days ago
How does one whitelist open("/dev/null") with seccomp-bpf?
3 comments

You can open /dev/null at init time and then lock down open(). Sure - it's not always possible, but it's a solution.
That's definitely a way better strategy than what I said -- when your code is well-designed-enough for it to work.
That is the Capsicum model, disable open when you go into secure mode. Note you can allow passing of file descriptors and an external program can open new files for you if you allow this. Many single task programs do not need to open files after initialisation.
I knew someone would ask that.

So, the way I'd recommend doing the filename whitelist is by setting up a mount namespace. Create a tmpfs, create the necessary directory tree inside it, bind-mount each whitelisted path in the tmpfs to the real file, then pivot_root into the tmpfs. This sounds complicated but is actually not very much code, and again a library could make it easier.

But I think you could also do it with pure seccomp. The trick is to copy the filename list into memory pages that you subsequently mark read-only. Then, have your seccomp filter whitelist specifically pointers to those strings, and prohibit making the pages writable again.

(Disclaimer: I just came up with this on a whim, it probably needs more thought.)

You don't even have to copy the filenames around and mess with changing page permissions - simply doing:

  static const char * const dev_null = "/dev/null";
and then whitelisting the pointer dev_null is sufficient, because string literals are stored in the text section which is mapped read-only.
That only works if you've locked down mprotect, mmap, and munmap.
Yes, the parent covered that.
> Create a tmpfs, create the necessary directory tree inside it, bind-mount each whitelisted path in the tmpfs to the real file, then pivot_root into the tmpfs

You've made an excellent case for pledge("rpath", ["/dev/null"]);

I am saying we can and should have a library that offers that interface, yes, but that having the lower-level building blocks available is also important.
AFAIK one can filter on the syscall's arguments.

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux....

I think it's quite readable and one could modify it easily to whitelist open on "/dev/null".