blob: caf01244e32737c29db72f4723395130d9585a91 [file] [log] [blame] [view]
# Unsafe code in Rust
`unsafe` is a dangerous but sometimes necessary escape hatch in Rust.
When writing or reviewing `unsafe` code, it's essential that you:
- clearly identify all of the assumptions and invariants required by every
`unsafe` block;
- ensure that those assumptions are met;
- ensure that those assumptions will *continue* to be met.
In order to ensure that `unsafe` invariants are not broken by future editors,
each usage of `unsafe` must be accompanied by a clear, concise comment
explaining what assumptions are being made.
Where possible, package up unsafety into a single function or module that
provides a safe abstraction to the outside world. FFI calls should usually
be exposed through a safe function whose only purpose is to provide a safe
wrapper around the function in question. These functions should contain
a comment with the following information (if applicable):
- Preconditions (e.g. what are the valid states of the arguments?)
- Failure handling (e.g. what values should be free'd? forgotten? invalidated?)
- Success handling (e.g. what values are created or consumed?)
Example:
```rust
impl Channel {
/// Write a message to a channel. Wraps the
/// [zx_channel_write](//docs/zircon/syscalls/channel_write.md)
/// syscall.
pub fn write(&self, bytes: &[u8], handles: &mut Vec<Handle>)
-> Result<(), Status>
{
let opts = 0;
let n_bytes = try!(usize_into_u32(bytes.len()).map_err(|_| Status::OUT_OF_RANGE));
let n_handles = try!(usize_into_u32(handles.len()).map_err(|_| Status::OUT_OF_RANGE));
// Requires that `self` contains a currently valid handle or ZX_HANDLE_INVALID.
// On success, all of the handles in the handles array have been moved.
// They must be forgotten and not dropped.
// On error, all handles are still owned by the current process and can be dropped.
unsafe {
let status = sys::zx_channel_write(self.raw_handle(), opts, bytes.as_ptr(), n_bytes,
handles.as_ptr() as *const sys::zx_handle_t, n_handles);
ok(status)?;
// Handles were successfully transferred, forget them on sender side
handles.set_len(0);
Ok(())
}
}
}
```
If `unsafe` code relies on other safe code for correctness, a comment
must be left alongside the corresponding safe code indicating what invariants
it must uphold and why. Invariants that rely upon the behavior of multiple
functions will draw extra scrutiny, and cross-module or cross-crate unsafety
requires even more attention. `unsafe` code that depends on correct behavior of
a third-party crate will likely be rejected, and `unsafe` code that depends
upon the internal representation details of third-party types will _never_ be
accepted.
Finally, `struct` definitions containing `unsafe` types such as `*const`,
`*mut`, or `UnsafeCell` must include a comment explaining the internal
representation invariants of the type. If the `unsafe` type is used to perform
a mutation OR if it aliases with memory inside another type, there should be
an explanation of how it upholds Rust's "aliasing XOR mutation" requirements.
If any `derive`able traits are purposefully omitted for safety reasons, a
comment must be left to prevent future editors from adding the unsafe impls.
The rules above are applied to any additions of `unsafe` code or any
modifications of existing `unsafe` code.
For more discussion on encapsulating `unsafe` invariants, see
[Ralf Jung's "The Scope of Unsafe"][scope-of-unsafe] and
[Niko Matsakis's "Tootsie Pop" model][tootsie-pop].
## Unsafe Reviews
To request an unsafe review for Rust code:
1. File a bug under the `Rust>Unsafe` component. Include a link to your review
in the bug description.
1. Add "Fuchsia Rust Unsafe Reviews <fuchsia-rust-unsafe-reviews@google.com>"
as a reviewer to your CL. A reviewer will be chosen at random and assigned
to your CL.
If your review is time-sensitive, increase the priority on your bug and leave a
comment explaining your situation.
[scope-of-unsafe]: https://www.ralfj.de/blog/2016/01/09/the-scope-of-unsafe.html
[tootsie-pop]: http://smallcultfollowing.com/babysteps/blog/2016/05/27/the-tootsie-pop-model-for-unsafe-code