5 ms·
Sounds like this could be implemented on Linux as a library on top of seccomp. I'm not impressed by De Raadt's objection to seccomp. BPF programs may technical
by kentonv 11y ago
Sounds like this could be implemented on Linux as a library on top of seccomp.
I'm not impressed by De Raadt's objection to seccomp. BPF programs may technically be turing-complete, but most of the things pledge() does can be implemented by a pretty simple seccomp filter that's just a flat list of conditionals implementing a whitelist or blacklist.
Meanwhile De Raadt points out, correctly, that voluntary security mechanisms will be ignored by most developers... but pledge() appears to be voluntary.
Seccomp-bpf is often used by sandboxes like Chrome or Sandstorm.io (of which I am lead developer), where it is not voluntary for the code that ends up being run inside the sandbox. But sandbox developers are likely to want seccomp's customizeability over pledge's ease-of-use.
So while it's nice that that pledge() is so easy to use, it strikes me that it's targeting the wrong audience with that design.
- tedunangst 11y agoHow does one whitelist open("/dev/null") with seccomp-bpf?
- kentonv 11y agoI 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.)
- MBCook 11y ago> 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"]);
- kentonv 11y agoI 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.
- caf 11y agoYou 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.
- viraptor 11y agoYou can open /dev/null at init time and then lock down open(). Sure - it's not always possible, but it's a solution.
- kentonv 11y agoThat's definitely a way better strategy than what I said -- when your code is well-designed-enough for it to work.
- justincormack 11y agoThat 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.
- leni536 11y agoAFAIK one can filter on the syscall's arguments. https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/samples/seccomp/bpf-fancy.c 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".
- protomyth 11y agoYour missing the point of pledge. It's for the developer to protect their code from the outside world. A malicious developer won't let we this and will try to obfuscate their intent and code. This is for the honest developer to mitigate the risk of a programming blunder to become a major exploit. Yes, its voluntary, but the developer has a self interest in using it.
- kentonv 11y agoNo, I completely understand that that's the point of pledge. But De Raadt's own slide 5 makes a convincing case that "optional security is irrelevant", and he dismisses SE Linux on that basis. I don't see why the same doesn't apply to pledge. Don't get me wrong, I think it's great for this to be available and I would like to see a similar, easy-to-use seccomp wrapper available on Linux. But, sadly, app developers aren't likely to use it.
- mjn 11y agoI'm extrapolating a bit here, since it's not that clear from the slides whether this is precisely what he meant, but I interpreted him to be criticizing optional security on the user side, which SELinux is. Since it's a set of user-configurable local system policies, users can, and often do, just use the most permissive policy possible to avoid having to debug SELinux problems. pledge() is optional from the perspective of the developer, but not the user, so once some piece of software implements it, it gets the protections without users having to set up an optional security policy, or being able to disable the one-and-only-one security policy (short of editing the pledge() calls out of the software and recompiling). And I gather that the OpenBSD developers will be patching software in the ports tree themselves, even if upstream doesn't, so that the OpenBSD version of as much software as possible uses it.
- kentonv 11y agoIn practice SE Linux policies are typically maintained by distros, which seems similar to OpenBSD adding pledge() to ports. I'll grant that pledge() will likely have an easier time expressing meaningful policies for many apps, though, since it is applied after initialization and with knowledge of command-line parameters, etc. OTOH, the set of policies expressible with pledge() is much more limited. But I really don't believe that user optional vs. developer optional makes a difference. The fact is that most app developers do not care to constrain themselves with mitigation layers. Most probably have no idea that this is even a thing they should consider, and of those that do most have other things they'd rather think about. Mitigation layers don't add new features and only fix hypothetical bugs which, sadly, most developers just don't care about.
- justin_vanw 11y agoYou are completely missing the entire point, you should figure out what you are missing here.
- Canada 11y ago> pledge() appears to be voluntary. As they've used it so far it's not that voluntary for the user. When De Raadt says voluntary mitigations don't work, he's talking about mitigations that a sysadmin can easily disable via settings. Unless developers build options to control it at runtime then in practice pledge() is a lot less voluntary than SE Linux which has a knob to enable or disable system-wide.
- antocv 11y agoOh hey sandstorm.io I tried your stuff, and was discouraged by the "pipe this script which will make modifications to your personal operating system into bash", why cant you just make a normal package which extracts to / like every other software does?