`cell-project` used incorrect variance when projecting through `&Cell<T>`
Key facts
- Attack vector
- —
- Privileges required
- —
- User interaction
- —
- Attack complexity
- —
- Impact type
- —
- Confidentiality · integrity · availability
- —
- Fix status
- Fixed
No CVSS vector from any source. Fix status from GitHub.
Summary
## Overview The issue lies in the implementation of the `cell_project` macro which used `field as *const _` instead of `field as *mut _`. The problem being that `*const T` is covariant in `T` while `*mut T` is invariant in `T`. Keep in mind that `&Cell<T>` is invariant in `T`, so casting to `*const T` relaxed the variance, and lead to unsoundness, as shown in the example below. ```rs use std::cell::Cell; use cell_project::cell_project as cp; struct Foo<'a> { x: Option<&'a Cell<Foo<'a>>>, } impl<'a> Drop for Foo<'a> { fn drop(&mut self) { // `ourselves` is an &Cell<Self>. // NB: `Drop` is unsound. if let Some(ourselves) = self.x.as_ref() { // replace `self` (but this doesn't actually replace `self`) let is_x_none = ourselves.replace(Foo { x: None, }).x.as_ref().is_none(); // if we just moved out of `self`, and we had a `Some` originally, // how come this is a `None`? if is_x_none { println!("how did we get a None?"); } } } } fn main() { let foo = Cell::new(Foo { x: None, }); let x = cp!(Foo<'_>, foo.x); x.set(Some(&foo)); } ``` ### MIRI error ```rs $ cargo +nightly miri run Finished dev [unoptimized + debuginfo] target(s) in 0.01s Running `<snip>` error: Undefined Behavior: not granting access to tag <untagged> because incompatible item is protected: [Unique for <2472> (call 796)] --> $RUST_STD_PATH/src/rust/library/core/src/cell.rs:404:31 | 404 | mem::replace(unsafe { &mut *self.value.get() }, val) | ^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <untagged> because incompatible item is protected: [Unique for <2472> (call 796)] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information = note: inside `std::cell::Cell::<Foo>::replace` at $RUST_STD_PATH/src/rust/library/core/src/cell.rs:404:31 note: inside `<Foo as std::ops::Drop>::drop` at src/main.rs:14:29 --> src/main.rs:14:29 | 14 | let is_x_none = ourselves.replace(Foo { | _____________________________^ 15 | | x: None, 16 | | }).x.as_ref().is_none(); | |______________^ = note: inside `std::ptr::drop_in_place::<Foo> - shim(Some(Foo))` at $RUST_STD_PATH/src/rust/library/core/src/ptr/mod.rs:486:1 = note: inside `std::ptr::drop_in_place::<std::cell::UnsafeCell<Foo>> - shim(Some(std::cell::UnsafeCell<Foo>))` at $RUST_STD_PATH/src/rust/library/core/src/ptr/mod.rs:486:1 = note: inside `std::ptr::drop_in_place::<std::cell::Cell<Foo>> - shim(Some(std::cell::Cell<Foo>))` at $RUST_STD_PATH/src/rust/library/core/src/ptr/mod.rs:486:1 note: inside `main` at src/main.rs:32:1 --> src/main.rs:32:1 | 32 | } | ^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace error: aborting due to previous error ``` ## Affected Versions All versions of the cell-project crate before `0.1.4` are affected. ## Mitigation This was fixed in [Issues/4], and released as version `0.1.4`. So just updating to the latest version will include the fix (which may result in a compile error on unsound usage). ## Acknowledgements This was discovered and fixed by @SoniEx2 in cell-project: [Issues/3] and [Issues/4] [issues/3]: https://github.com/RustyYato/cell-project/issues/3 [issues/4]: https://github.com/RustyYato/cell-project/issues/4
Why it matters now
SSVC decision points
Not available: CISA has not published SSVC decision points for this record.
Affected products
| Vendor | Product | Affected versions | Fixed in | Status | Source |
|---|---|---|---|---|---|
| — | cell-project (crates.io) | before 0.1.4 | 0.1.4 | Patch available | GHSA-p75v-367r-2v23 |
- cell-project (crates.io) Vendor— Affected before 0.1.4 Fixed in 0.1.4 Patch available GHSA-p75v-367r-2v23
Remediation
- Fix · GHSA-p75v-367r-2v23 cell-project (crates.io) Fixed in 0.1.4 Advisory →
Timeline
- 2026-10-03 Threatist record created from GHSA-p75v-367r-2v23
References
Sources
This product uses the NVD API but is not endorsed or certified by the NVD. Sources and licences