I gotta comment.. >> The tool makes essential use of the execpromises argument >> to pledge(2), so that it can sandbox the program it executes. > >This appears to conflict with the basic idea of pledge(2), which >is for the *programmer* to first do simple preparatory work that >requires full syscall access, then pledge(2) according to a precise >understanding of what the program is supposed to do during normal >operation. Usually, it is not possible to properly pledge(2) a >program without designing it for pledge(2), sometimes called >"hoisting".
In the simplest cases, pledge removes some support operations, in particular relating options hiding under ioctl. More complicated pledge use cases follow a "successive drop" feature as program initialization starts. With this kind of pledge-from-parent, the sophisticated cases are impossible. Sadly, almost all programs bigger than "cat" or "more" require a huge pledge for initalization, especially if they do accept environment variables (themselves or in libc), or use the network. So the pledge will always be huge. >As a corollary, pledging a program from the outside, >without changing the code that is compiled, usually does not >provide significant benefit. I agree. I wrote a command like this myself, when I developed the execpromises featureset. I am ready to delete exec promises because I consider it a failed experiment. I found that useful application was extremely rare. I could not even use execpromises properly in programs like "disklabel -E" to control the behaviour of the $EDITOR. I've been down this road before, and it doesn't work. You can come to this conclusion by finding a program, and trying *absolutely everything* it does, including environment variables and file openings and such that the libraries do. You'll begin with optimism, but eventually add more and more pledges. There's one more thing I want to mention: pledge("shitload of options") intentionally is a non-POSIX compliant environment. Command line users won't understand the edge conditions.