GHSA-p75v-367r-2v23: Cell project `cell-project` Used Incorrect Variance When Vulnerability

MODERATE
Published
Advisory Summary

GHSA-p75v-367r-2v23 is a MODERATE `cell-project` used incorrect variance when vulnerability (General Security Weakness) affecting Cell project libraries in the crates.io ecosystem. The issue involves `cell-project` used incorrect variance when projecting through `&cell<t>`. Remediation is available by upgrading affected packages to version 0.1.4.

GHSA-p75v-367r-2v23 at a Glance

CVE Identifier N/A
GHSA Identifier GHSA-p75v-367r-2v23
Severity MODERATE
CVSS v3.1 Base Score N/A
CWE Classification General Security Weakness
Affected Product Cell project
Package Ecosystem crates.io
Published Date
Last Updated

How to Fix GHSA-p75v-367r-2v23

To remediate this vulnerability, upgrade all affected Cell project dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

cell-project fixed: 0.1.4
Upgrade cell-project to 0.1.4
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for cell-project

How to Check if You Are Affected

To determine whether your application is affected by GHSA-p75v-367r-2v23, inspect your project dependencies for Cell project:

inspect dependencies for cell-project

Analyze the terminal output to locate any version of Cell project in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.1.4), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under General Security Weakness. In Cell project, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## 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

GHSA-p75v-367r-2v23 Affected Cell project Versions

1 component(s)
Fixed Versions:
0.1.4
Product / Package Ecosystem Affected Versions Fixed Version
cell-project
crates.io
< 0.1.4
0.1.4

References

Frequently Asked Questions

What is GHSA-p75v-367r-2v23?
GHSA-p75v-367r-2v23 is a security vulnerability in Cell project involving `cell-project` used incorrect variance when projecting through `&Cell<T>` under General Security Weakness.
Which Cell project versions are affected?
Affected versions include releases prior to 0.1.4 across affected packages: cell-project.
What version fixes GHSA-p75v-367r-2v23?
Upgrading to 0.1.4 (or the latest patched release for your respective branch) resolves the vulnerability.
Is cell-project affected?
Yes, cell-project is affected in releases prior to 0.1.4. Upgrade your dependency to 0.1.4 or later.
What CWE is associated with GHSA-p75v-367r-2v23?
GHSA-p75v-367r-2v23 is classified under General Security Weakness.
How can I check crates.io dependencies for GHSA-p75v-367r-2v23?
Run the dependency tree command: 'inspect dependencies for cell-project'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "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<T>`",
  "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<T>` 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<Foo<'a>>>,\n}\n\nimpl<'a> Drop for Foo<'a> {\n    fn drop(&mut self) {\n        // `ourselves` is an &Cell<Self>.\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 `<snip>`\nerror: Undefined Behavior: not granting access to tag <untagged> 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 <untagged> 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::<Foo>::replace` at $RUST_STD_PATH/src/rust/library/core/src/cell.rs:404:31\nnote: inside `<Foo as std::ops::Drop>::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::<Foo> - 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::<std::cell::UnsafeCell<Foo>> - shim(Some(std::cell::UnsafeCell<Foo>))` at $RUST_STD_PATH/src/rust/library/core/src/ptr/mod.rs:486:1\n    = 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\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
  }
}