Index | Thread | Search

From:
"Theo de Raadt" <deraadt@openbsd.org>
Subject:
Re: openat(2) is mostly useless, sadly
To:
"H. Hartzer" <h@hartzer.sh>, tech@openbsd.org
Date:
Fri, 30 May 2025 14:53:08 -0600

Download raw body.

Thread
O_BELOW is a shortcut for open() so you can set the F_BELOW flag when
you open the initial directory.  O_BELOW allows you to skip calling
fcntl with F_BELOW -- you can do it in one system call, with one -1
errno check.  The fcntl F_BELOW method still needs to exist because a
dirfd may come from somewhere else, and setting the flag late will be
neccessary.

O_BELOW is not an flag passed to the later openat calls relative to
the directory, it is a flag set on the 'atfd' aka 'dirfd'.

OTOH, O_BENEATH and family, and other somewhat related things in Linux,
are flags you set when performing the relative operations -- against a
regular dirfd which has no restrictions.  I think the people involved in
those designs got the problem wrong.

Simply, F_BELOW is a directory fd attribute / capability, as opposed
to the functional methods other systems chose to use.

Those functional methods have not gained much use.  I think this is because
if you miss adding the flag bit in one functional access operation, you
escape the boundaries silently without noticing.

Secondly, if your code gets holed, you can pass the dirfd to any openat
call without the flag bit, and it will gladly let you escape.

The only secure scheme is to add a restrictive capability mode on the
dirfd, which permanently locks use to downwards path resolutions.  And
to make that setting irreverseable, as I've done in the code.


But now I'm explaining it again, to people who apparently didn't read the
original email, haven't compiled a kernel, and haven't tried to use it
in practice... maybe I should go back to designing extensions in more
private forums.