Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document soundness status #31

Merged
merged 2 commits into from
Aug 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,30 @@
bindings for io_uring, the hottest
thing to happen to linux IO in a long time.

#### Soundness status

rio aims to leverage Rust's compile-time checks to be
misuse-resistant compared to io_uring interfaces in
other languages, but users should beware that
**use-after-free bugs are still possible without
`unsafe` when using rio.** `Completion` borrows the
buffers involved in a request, and its destructor
blocks in order to delay the freeing of those buffers
until the corresponding request has completed; but it
is considered safe in Rust for an object's lifetime
and borrows to end without its destructor running,
and this can happen in various ways, including
through `std::mem::forget`. Be careful not to let
completions leak in this way, and if Rust's soundness
guarantees are important to you, you may want to
avoid this crate.

#### Innovations

* only relies on libc, no need for c/bindgen to
complicate things, nobody wants that
* the completions work great with threads or an
async runtime (`Completion` implements Future)
* takes advantage of Rust's lifetimes and RAII to guarantee
that the kernel will never asynchronously write to memory
that Rust has destroyed.
* uses Rust marker traits to guarantee that a buffer will never
be written into unless it is writable memory. (prevents
you from trying to write data into static read-only memory)
Expand Down
9 changes: 5 additions & 4 deletions src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ impl Default for CompletionState {
///
/// # Safety
///
/// Never call `std::mem::forget` on this value.
/// It can lead to a use-after-free bug. The fact
/// that `std::mem::forget` is not marked unsafe
/// is a bug in the Rust standard library.
/// To prevent undefined behavior in the form of
/// use-after-free, never allow a Completion's
/// lifetime to end without dropping it. This can
/// happen with `std::mem::forget`, cycles in
/// `Arc` or `Rc`, and in other ways.
#[derive(Debug)]
pub struct Completion<'a, C: FromCqe> {
lifetime: PhantomData<&'a C>,
Expand Down