This review is from Crev, a distributed system for code reviews. To add your review, set up cargo-crev
.
0.1.2 (current) Thoroughness: High Understanding: Medium
by yvt on 2021-09-18
This crate provides an atomic cell type named AtomicOption
to store
Box<T>
.
This crate is severely flawed and unsound but not malicious, hence the negative rating.
Marking as unmaintained because of several serious issues being left unfixed for at least a year.
Major issues
Underconstrained memory ordering
AtomicOption
's methods allow the caller to specify memory orderings weaker
than what would be safe. Consider the following two processes:
// Process 1:
1 let mut boxed = Box::new(1);
2 *boxed = 2;
3 atom_opt.swap(boxed, Ordering::Relaxed);
// Process 2:
4 let boxed = atom_opt.take(Ordering::Relaxed).unwrap();
5 dbg!(*boxed);
Process 1 performs two writes on *boxed
at line numbers 1 and 2. Supposing
Process 2 observes the boxed
sent by Process 1 at line number 4, it performs
one read on *boxed
at line number 5. Since the writes and read are not
ordered properly, the read creates an undef
value.
There's a three year old GitHub issue reporting this problem.
Pointer-to-integer transmutation
This crate uses pointer-to-integer transmutation, which has unresolved issues
regarding pointer provenance1. This could be safely avoided by replacing
the internally-used AtomicUsize
with AtomicPtr
.
Incorrect Sync
bounds
AtomicOption
unconditionally implements Sync
, which allows T: !Send
to
be sent to another thread through &AtomicOption
. There's a RustSec
advisory regarding this issue.
Minor issues
The documentation of the unsafe fn
AtomicOption::from_raw
doesn't describe
the safe usage.
The use of SeqCst
in AtomicOption::drop
suggests the author's lack of
understanding in atomics and memory ordering.
Good things
The crate is quite small as it contains only about 200 lines (including comments) of Rust code.
-
Issue: High (RUSTSEC-2020-0113)
Incorrect
Sync
bounds -
Issue: High (github.com/reem/rust-atomic-option/issues/3)
Underconstrained memory ordering
Crates in the crates.io registry are tarball snapshots uploaded by crates' publishers. The registry is not using crates' git repositories. There is absolutely no guarantee that the repository URL declared by the crate belongs to the crate, or that the code in the repository is the code inside the published tarball.
To review the actual code of the crate, it's best to use cargo crev open atomic-option
. Alternatively, you can download the tarball of atomic-option v0.1.2 or view the source online.
In the affected versions of this crate,
AtomicOption<T>
unconditionally implementsSync
.This allows programmers to move non-Sync types across thread boundaries (e.g.
Rc<T>
,Arc<Cell<T>>
), which can lead to data races and undefined behavior. It is also possible to send non-Send types likestd::sync::MutexGuard
to other threads, which can lead to undefined behavior.CVE-2020-36219
GHSA-8gf5-q9p9-wvmc