Skip to content

Adding less idiomatic, but more accurate wrappers? #25

Open
@cyphar

Description

@cyphar

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:

  1. 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 the renameat2 wrappers can only be used to a rename between two paths with the same Dir -- this is simply not useable for my usecase with libpathrs (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 different Dirs).

  2. 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 specify O_NOFOLLOW or the non-openat(2) equivalent then you simply cannot be secure against certain attacks (in the libpathrs usecase). To be fair, I do agree with your splitting of the functionality of renameat2(2) -- it does three different things (though you didn't expose RENAME_NOREPLACE). Not to mention the lack of O_PATH support -- which is ridiculously critical for libpathrs (the entire library depends on very specific semantics that O_PATH file descriptors provide).

  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions