Index | Thread | Search

From:
"Theo de Raadt" <deraadt@openbsd.org>
Subject:
Re: Locking down openat(2) and friends with O_BELOW and F_BELOW
To:
Christian Schulte <cs@schulte.it>
Cc:
tech@openbsd.org
Date:
Sun, 04 Oct 2026 16:52:20 -0600

Download raw body.

Thread
Christian Schulte <cs@schulte.it> wrote:

> > +	case F_BELOW:
> > +		vp = fp->f_data;
> > +	        if (fp->f_type == DTYPE_VNODE && vp->v_type == VDIR)
> > +			fp->f_flag |= O_BELOW;
> > +		else
> > +			return ENOTTY;
> 
> I am not sure about using ENOTTY here. The changes to the manuals do not
> say much about it. The ERROR section of fcntl(2) does not mention
> ENOTTY. But that may just be me stumbling upon an identifier during a
> quick read expecting EINVAL.

Will reconsider.

> > +		break;
> > +
> >  	case F_DUPFD:
> >  	case F_DUPFD_CLOEXEC:
> >  	case F_DUPFD_CLOFORK:
> > Index: bin/csh/exec.c
> > ===================================================================
> > RCS file: /cvs/src/bin/csh/exec.c,v
> > diff -u -r1.22 exec.c
> > --- bin/csh/exec.c	8 Mar 2023 04:43:04 -0000	1.22
> > +++ bin/csh/exec.c	18 Sep 2026 20:35:42 -0000
> > @@ -439,6 +439,7 @@
> >  	dirp = opendir(short2str(*pv));
> >  	if (dirp == NULL)
> >  	    continue;
> > +	fcntl(dirfd(dirp), F_BELOW);
> 
> You sometimes just add that line and sometimes guard it with
> 
> #ifdef F_BELOW
> #endif
...
> Like here. From just reading the diff it is not abvious why the guards
> are used sometimes and sometimes not. That does not mean there is
> anything wrong about it. Just does not read intuitively.

We'll need the #ifdef in software we distribute as -portable, but I
haven't been consistant about it yet since this is a draft, and I'm hoping
various people will consider this new approach.