From: "Theo de Raadt" Subject: Re: fix calendar -a To: Alexander Bluhm , tech Date: Mon, 16 Mar 2026 11:12:20 -0600 Stuart Henderson wrote: > On 2026/03/16 11:01, Theo de Raadt wrote: > > Stuart Henderson 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).