Re: curtain: WIP sandboxing mechanism with pledge()/unveil() support

From: Mathieu <>
Date: Thu, 31 Mar 2022 23:07:37 UTC
On 3/31/22 15:37, Shawn Webb wrote:
> On Thu, Mar 31, 2022 at 03:33:06PM -0400, Ed Maste wrote:
>> On Thu, 31 Mar 2022 at 06:25, David Chisnall <> wrote:
>>> Capsicum simply disallows '..' in paths.
>> This is no longer true as of 7359fdcf5ffa. During a lookup the kernel
>> checks that each ".." component specifies a directory that has already
>> been visited in this name lookup call.
>>> The execve hole is the reason that I have little interest in pledge as
>>> an enforcement mechanism.
>> Note that execve is only available if the "exec" keyword is specified.
>> The child does not inherit the parent's limits, though.

It does not inherit the restrictions passed as pledge()'s first 
argument, but it gets the restrictions passed as the second argument (if 
it is non-NULL) and it can't get rid of those ever. If the executed 
programs then execute other programs, they will also be restricted to a 
subset of those restrictions.

But you have to actually make use of the second argument (but the child 
program might not be able to tolerate it...).

> I wonder if there's opportunity here for a little divergence. I think
> inheritance would be a good thing. But this is more a philosophical
> and subjective argument than a technical one.

There's divergeance in my module already, but I tried to keep the 
pledge() implementation compatible.

If you use pledge() alone, this (hopefully) makes no significant difference.

But if you use curtain(1), curtain(3) directly or the 
freebsd_simple_sandbox() wrapper I added, sandbox restrictions are all 
inherited (irreversibly) by default.

And if you use pledge() on top of an inherited curtain, the pledged 
applications can get rid of its own pledge restrictions on-exec, but it 
cannot get rid of the inherited curtain restrictions in any way.  
(Unless I screwed up!)

It's this whole pledge() execve() question that made me come up with an 
altered design that is fully nestable.  Now pledge() support is sort of 
"emulated" on top of the more general curtain mechanism.