pledge with a reëxecing process
I have a web application process, which talks to strangers on the network and stores data in the filesystem. To limit the damage caused by naughty tricksters, it uses pledge and unveil so that even if somebody takes over the process, they can only corrupt this program’s data. As opposed to changing my password, for example.
Users love features, so every day I add a new feature, and then I restart the server. This causes milliseconds of downtime. We can only afford 800 milliseconds of downtime per day in order to meet our five nines availability target, and two restarts in a single day puts us very close to the limit. So I added a smooth restart feature, where sending SIGHUP to the server will cause it to reëxec itself, but with the listening socket already open. No connections are lost.
Fork and exec require additional promises to pledge. But this opens the door to trouble. What happens if the trickster wants to exec a new process? Fortunately, unveil restricts exec to only the same program, but they can still restart it with new options, like setting the log file to /etc/passwd. The command line interface offers enough flexibility to accomplish a fair bit of mischief. I spent some time convincing myself this is an unlikely attack scenario, and mostly succeeded, but using pledge suggests I care about unlikely scenarios, so I should do things properly.
As with all problems, the solution is to add another layer of abstraction. Now the main process execs a worker process, and the worker process once again loses the ability to exec. I was already using one helper process anyway, managed by the server. After shuffling some code around, our growing family now includes three processes. The result is arguably better organized, as well, since competing concerns are better split among the processes.