That is probably the reason for the quick uptake of pledge in OpenBSD's tree. A lot of their software had already been restructured or rewritten for privilege separation. But looking at a few capsicum diffs in the FreeBSD codebase I'm not sure I'd call those trivial. You can do more with capscium so there is more code to deal with those abilities. But even simple cases hit 20+ lines of code with multiple failure states to deal with. Compared to the usual two line pledge diffs that's quite a bit more work to do.
> Compared to the usual two line pledge diffs that's quite a bit more work to do.
I don't think you're comparing apples and oranges. OpenBSD has just already done the restructuring as a separate commit; in FreeBSD you see it all at the same time, so it looks bigger. Capsicum for simple stuff is only a few lines, especially with the "helper" subroutines.
In some cases we can get more functionality with the same restriction, or more restriction than OpenBSD due to more specific constraints. So there's more code, but it also does more. It can be a trade-off.
That statement was comparing capsicum being applied to programs that were also pledged in around 2 lines of code. A few of the programs on the wiki as examples of capsicum applications originated from OpenBSD so they were primed and ready to go. Even those best cases are much more involved than pledge.
To use the example of the unix tr utility, the change to use pledge required the standard two line diff.
if (pledge("stdio", NULL) == -1)
err(1, "pledge");
tr.c was the one of the earliest programs pledged (back when it was called tame). The original diff was a one liner before they start doing the "pledge or error out".
+ cap_rights_init(&rights, CAP_FSTAT, CAP_IOCTL, CAP_READ);
+ if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS)
+ err(1, "unable to limit rights for stdin");
+ cap_rights_init(&rights, CAP_FSTAT, CAP_IOCTL, CAP_WRITE);
+ if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS)
+ err(1, "unable to limit rights for stdout");
+ if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS)
+ err(1, "unable to limit rights for stderr");
+
+ /* Required for isatty(3). */
+ cmd = TIOCGETA;
+ if (cap_ioctls_limit(STDIN_FILENO, &cmd, 1) < 0 && errno != ENOSYS)
+ err(1, "unable to limit ioctls for stdin");
+ if (cap_ioctls_limit(STDOUT_FILENO, &cmd, 1) < 0 && errno != ENOSYS)
+ err(1, "unable to limit ioctls for stdout");
+ if (cap_ioctls_limit(STDERR_FILENO, &cmd, 1) < 0 && errno != ENOSYS)
+ err(1, "unable to limit ioctls for stderr");
+
+ if (cap_enter() < 0 && errno != ENOSYS)
+ err(1, "unable to enter capability mode");
No one would dispute that capsicum is more capable but is significantly more complex. Pledge trades finer control over capabilities for the ability to have a "work or die" usage model. Capsicum requires that you be aware of all the potential failure cases and account for them.