Description
I'm bringing this up because of a discussion with @cgwalters about this crate (see openSUSE/libpathrs#1). libpathrs
is a library which helps correctly handle path resolution in the face of potential attackers. To this end, I make use of a lot of different *at
syscalls -- but because it is a security-sensitive project I am very wary of how Rust crates use different syscalls (to the point where I audited the key methods in the Rust standard library I used, to ensure they did the right thing -- see rust-lang/rust#62425).
@cgwalters asked me whether I could use this library for libpathrs
in order to help consolidate Rust *at
-using programs to make use of a single library. I took a look, and unfortunately several aspects of the current API concern me a little bit (at least, for the use-case I have). There are three main problems I saw:
-
The API is designed around a
Dir
object, with everything being a method of such an object. This is probably the most obvious way of doing it, given how all of the*at(2)
documentation is written -- but it's not the most useful.AT_EMPTY_PATH
(or various other/proc/self/fd
tricks) allows you to operate on non-directories, and there are many use-cases for wanting to do that. Another example of this problem is that therenameat2
wrappers can only be used to a rename between two paths with the sameDir
-- this is simply not useable for my usecase withlibpathrs
(I must be able to do all*at(2)
operations without any/
s in the paths, because that leads to serious attack vectors -- and so I need to use two differentDir
s). -
The flags for all the
*at(2)
syscalls are not exposed by this crate. While this might make the API much simpler, it seriously restricts the usability of the*at(2)
wrappers provided -- as a simple example, if you cannot explicitly specifyO_NOFOLLOW
or the non-openat(2)
equivalent then you simply cannot be secure against certain attacks (in thelibpathrs
usecase). To be fair, I do agree with your splitting of the functionality ofrenameat2(2)
-- it does three different things (though you didn't exposeRENAME_NOREPLACE
). Not to mention the lack ofO_PATH
support -- which is ridiculously critical forlibpathrs
(the entire library depends on very specific semantics thatO_PATH
file descriptors provide). -
While there is some documentation for the methods, I would love to have much more detailed documentation about the security properties (even something as basic as showing what syscalls are called by a given method). For security-critical projects i
My main question is, would you be interested in working together to create an API that can accommodate my requirements while also providing more idiomatic helper wrappers that less-insane users can make use of? Currently libpathrs
has its own wrappers (which I trust and understand because I wrote them), but it makes little sense for every project to write their own wrappers for a dozen syscalls.
There is also some hardening work within libpathrs
(such as getting a handle to /proc
when the library is first loaded, checking that it really is procfs and then using it for all /proc
-related shenanigans). It would be nice if things like that were put into this project as well.
Thanks.