Index | Thread | Search

From:
"Theo de Raadt" <deraadt@openbsd.org>
Subject:
Re: fix calendar -a
To:
Alexander Bluhm <bluhm@openbsd.org>, tech <tech@openbsd.org>
Date:
Mon, 16 Mar 2026 11:12:20 -0600

Download raw body.

Thread
Stuart Henderson <stu@spacehopper.org> wrote:

> On 2026/03/16 11:01, Theo de Raadt wrote:
> > Stuart Henderson <stu@spacehopper.org> wrote:
> > 
> > > On 2026/03/16 10:45, Theo de Raadt wrote:
> > > > I doubt you need "rx".
> > > > 
> > > > Does "x" not work?
> > > 
> > > it does, but / is already unveiled 'r' so using just 'x' for those
> > > doesn't seem any better?
> > 
> > Whoa, I am hearing a big misunderstanding.
> > 
> > Unveil creates a series of nested enclaves.
> > 
> > The permissions from a higher level are IRRELEVANT in a nested enclave.
> > 
> > If you do
> > 
> >    unveil("/", "r");
> >    unveil("/bin/ksh", "x);
> > 
> > That does not allow you read /bin/ksh.
> > 
> 
> 
> Index: calendar.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/calendar/calendar.c,v
> diff -u -p -r1.41 calendar.c
> --- calendar.c	16 Mar 2026 16:58:03 -0000	1.41
> +++ calendar.c	16 Mar 2026 17:05:49 -0000
> @@ -130,12 +130,12 @@ main(int argc, char *argv[])
>  			err(1, "unveil /tmp");
>  		if (unveil("/dev/null", "rw") == -1)
>  			err(1, "unveil /dev/null");
> -		if (unveil(_PATH_SENDMAIL, "rx") == -1)
> -			err(1, "unveil " _PATH_SENDMAIL);
> -		if (unveil(_PATH_CPP, "rx") == -1)
> -			err(1, "unveil " _PATH_CPP);
>  		if (unveil("/", "r") == -1)
>  			err(1, "unveil /");
> +		if (unveil(_PATH_SENDMAIL, "x") == -1)
> +			err(1, "unveil " _PATH_SENDMAIL);
> +		if (unveil(_PATH_CPP, "x") == -1)
> +			err(1, "unveil " _PATH_CPP);
>  		if (pledge("stdio rpath wpath cpath fattr getpw id proc exec",
>  		    NULL) == -1)
>  			err(1, "pledge");

OK

Something else is also showing up in your diff.

The order of unveils don't matter!


What unveil does is traverse an open (meaning nothing prevents finding
files) filesystem and collect vnodes, which are refcnt++'d so they don't
go away.  For this process these vnodes are remembered.  There are two
ways they are remembered: As a vnode, or as a vnode dir with a filename
in that directory (file  may or may not exist).

When the unveil rules gets activated (unveil(NULL, NULL) or pledge w/o
"unveil"), then future path lookups are compared according to those
remembered vnodes.

That's why the order of unveil operations don't matter.

It is still stylistically better to put the largest filesystem space before
the more localized paths, because a consistant ree view is easier for poeple
to review (idiomatically).