{ "schema_version": "1.4.0", "id": "GHSA-p75v-367r-2v23", "modified": "2022-09-16T21:08:19Z", "published": "2022-09-16T21:08:19Z", "aliases": [], "summary": "`cell-project` used incorrect variance when projecting through `&Cell`", "details": "## Overview\n\nThe issue lies in the implementation of the `cell_project` macro which used `field as *const _` instead of `field as *mut _`.\nThe problem being that `*const T` is covariant in `T` while `*mut T` is invariant in `T`. Keep in mind that `&Cell` is invariant in `T`,\nso casting to `*const T` relaxed the variance, and lead to unsoundness, as shown in the example below.\n\n```rs\nuse std::cell::Cell;\nuse cell_project::cell_project as cp;\n\nstruct Foo<'a> {\n x: Option<&'a Cell>>,\n}\n\nimpl<'a> Drop for Foo<'a> {\n fn drop(&mut self) {\n // `ourselves` is an &Cell.\n // NB: `Drop` is unsound.\n if let Some(ourselves) = self.x.as_ref() {\n // replace `self` (but this doesn't actually replace `self`)\n let is_x_none = ourselves.replace(Foo {\n x: None,\n }).x.as_ref().is_none();\n // if we just moved out of `self`, and we had a `Some` originally,\n // how come this is a `None`?\n if is_x_none {\n println!(\"how did we get a None?\");\n }\n }\n }\n}\n\nfn main() {\n let foo = Cell::new(Foo {\n x: None,\n });\n let x = cp!(Foo<'_>, foo.x);\n x.set(Some(&foo));\n}\n```\n\n### MIRI error\n\n```rs\n$ cargo +nightly miri run\n Finished dev [unoptimized + debuginfo] target(s) in 0.01s\n Running ``\nerror: Undefined Behavior: not granting access to tag because incompatible item is protected: [Unique for <2472> (call 796)]\n --> $RUST_STD_PATH/src/rust/library/core/src/cell.rs:404:31\n |\n404 | mem::replace(unsafe { &mut *self.value.get() }, val)\n | ^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag because incompatible item is protected: [Unique for <2472> (call 796)]\n |\n = help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental\n = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information\n\n = note: inside `std::cell::Cell::::replace` at $RUST_STD_PATH/src/rust/library/core/src/cell.rs:404:31\nnote: inside `::drop` at src/main.rs:14:29\n --> src/main.rs:14:29\n |\n14 | let is_x_none = ourselves.replace(Foo {\n | _____________________________^\n15 | | x: None,\n16 | | }).x.as_ref().is_none();\n | |______________^\n = note: inside `std::ptr::drop_in_place:: - shim(Some(Foo))` at $RUST_STD_PATH/src/rust/library/core/src/ptr/mod.rs:486:1\n = note: inside `std::ptr::drop_in_place::> - shim(Some(std::cell::UnsafeCell))` at $RUST_STD_PATH/src/rust/library/core/src/ptr/mod.rs:486:1\n = note: inside `std::ptr::drop_in_place::> - shim(Some(std::cell::Cell))` at $RUST_STD_PATH/src/rust/library/core/src/ptr/mod.rs:486:1\nnote: inside `main` at src/main.rs:32:1\n --> src/main.rs:32:1\n |\n32 | }\n | ^\n\nnote: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace\n\nerror: aborting due to previous error\n```\n\n## Affected Versions\n\nAll versions of the cell-project crate before `0.1.4` are affected.\n\n## Mitigation\n\nThis was fixed in [Issues/4], and released as version `0.1.4`.\nSo just updating to the latest version will include the fix (which may result in a compile error on unsound usage).\n\n## Acknowledgements\n\nThis was discovered and fixed by @SoniEx2 in cell-project: [Issues/3] and [Issues/4]\n\n[issues/3]: https://github.com/RustyYato/cell-project/issues/3\n[issues/4]: https://github.com/RustyYato/cell-project/issues/4\n", "severity": [], "affected": [ { "package": { "ecosystem": "crates.io", "name": "cell-project" }, "ranges": [ { "type": "ECOSYSTEM", "events": [ { "introduced": "0" }, { "fixed": "0.1.4" } ] } ] } ], "references": [ { "type": "WEB", "url": "https://github.com/RustyYato/cell-project/issues/3" }, { "type": "WEB", "url": "https://github.com/RustyYato/cell-project/pull/4" }, { "type": "PACKAGE", "url": "https://github.com/RustyYato/cell-project" }, { "type": "WEB", "url": "https://rustsec.org/advisories/RUSTSEC-2020-0164.html" } ], "database_specific": { "cwe_ids": [], "severity": "MODERATE", "github_reviewed": true, "github_reviewed_at": "2022-09-16T21:08:19Z", "nvd_published_at": null } }