I noticed that you're missing the sendfd promise. Is there a reason for that omission? Also you've added a number of extensions that perhaps should be documented as such.
Also there's a pretty significant undocumented difference between your implementation and OpenBSD, in that promises are by inherited across exec in yours, and not on OpenBSD.
OpenBSD experimented with that by specifying the second argument as execpromises, but discovered that it was extremely difficult if not impossible to write meaningful execpromises in the parent for potentially unrelated programs, it's also happening too early before dynamic linking, and before the program has had an opportunity to "initialize" or "do privileged stuff" and call pledge(2) later itself with more accurate knowledge of what to self-restrict. As such, no calls with execpromises set to anything but NULL/0 exist today. I'm curious how to reconcile those differences.
sendfd is something we can add. Note that seccomp has limited visibility into recvmsg / sendmsg args because bpf can't dereference syscall arg pointers. I mention some of this in the caveats section. As for execpromises, it's documented in the Cosmopolitan Libc source code, but that got lost in translation when I copied the docs to the website. I just updated the site. I also appreciate the eyeballs. Something like this deserves critical examination. There's so much breadth to the modern system call interface and pledge. I started working on this about a month ago. With the support of folks like yourself, I think we'll have something really nice that will benefit Linux users! I'll definitely be doing more to make the C API as compatible with OpenBSD as possible.
> I'll definitely be doing more to make the C API as compatible with OpenBSD as possible.
One suggestion I might add, it would be worth trying to compile any of OpenBSD's privilege separated network daemons on Linux (w/ Cosmopolitan Libc, or others). While you may have intended to use this facility primarily for your own APE Binaries, I suspect you'll find that the despite your intentions to make this compatible with the C API definition of pledge(2), in practice, your implementation is incompatible with privsep/privdrop software, for which pledge was designed. It was never intended for application "sandboxing".
pledge() wasn't intended for our awesome sandboxing tool? Well that just goes to show how brilliant the OpenBSD developers are, that folks like myself are finding great uses for their ideas and design that they didn't intend. We might not be able to live up to OpenBSD's model given the way Linux is, but I do believe we're going to have a better and more secure Linux thanks to the influence of OpenBSD.
OpenBSD pledges aren’t normally used for child processes, they’re more for “okay this program has super well-defined needs, let’s make sure (in its own source code) that it won’t be able to do anything else”. So a wrapper program wouldn’t really be normal usage.
> Note that seccomp has limited visibility into recvmsg / sendmsg args because bpf can't dereference syscall arg pointers.
BPF programs attached to syscalls (via kprobe or fentry) can read arguments via helpers (bpf_probe_read_{user,kernel}). Seccomp uses "classic BPF" which has no concept of helpers or calls.
> Note that seccomp has limited visibility into recvmsg / sendmsg args because bpf can't dereference syscall arg pointers.
I guess landlock can't help you here since it is still mostly about filesystem access right now, but maybe someday? It looks like "minimal network access control" is on the long term roadmap: https://landlock.io/
I noticed that you're missing the sendfd promise. Is there a reason for that omission? Also you've added a number of extensions that perhaps should be documented as such.
Also there's a pretty significant undocumented difference between your implementation and OpenBSD, in that promises are by inherited across exec in yours, and not on OpenBSD.
OpenBSD experimented with that by specifying the second argument as execpromises, but discovered that it was extremely difficult if not impossible to write meaningful execpromises in the parent for potentially unrelated programs, it's also happening too early before dynamic linking, and before the program has had an opportunity to "initialize" or "do privileged stuff" and call pledge(2) later itself with more accurate knowledge of what to self-restrict. As such, no calls with execpromises set to anything but NULL/0 exist today. I'm curious how to reconcile those differences.