Making openat(2) and friends more useful in practice
31 points by fro
31 points by fro
Interesting, a kind of capsicum-lite, per-fd instead of per-process. I like the idea of fchdir() into an O_BELOW directory!
How does that differ from FreeBSD’s O_RESOLVE_BENEATH
?
From reading FreeBSD’s man page, I believe the distinction is that O_RESOLVE_BENEATH
affects what a single openat(2)
call can do but it doesn’t affect the descriptor that gets returned. A dirfd opened with O_BELOW
can never be used to travel above .
when used later. As Theo writes, “Both FreeBSD and Linux have designed variations which do this. Since all
the *at(2) functions have a flags parameter, their strategy was to add an additional flag which didn’t allow upwards traversal.”
That makes sense. In face of a current issue, FreeBSD considers adding such a flag. I’ll ask the parties involved to consider OpenBSD’s design.
My immediate question is how does O_BELOW
interact with symlinks? If I have a symlink below a dirfd
that points outside of it, and I don’t pass O_NOFOLLOW
, what happens?
It would seem from the patch (in the iteration Theo has shared so far) like you follow the symlink, in that nothing is newly telling it not to. But I imagine that in a situation where you’d open an fd O_BELOW
to use as a capability later in the program you also want to call unveil(2)
before that capability gets used to access a user-controlled path.
that looks like a good idea
i would use that in a build tool i’m writing, if it were available, as an easy way to tell if you broke hermeticity (unveil would also probably do the job. but, holding on to a few descriptors and being able to switch between them seems nice)