CVE-2020-35905
Description
An issue was discovered in the futures-util crate before 0.3.7 for Rust. MutexGuard::map can cause a data race for certain closure situations (in safe code).
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
In futures-util before 0.3.7, MutexGuard::map can cause a data race in safe code due to incorrect Send/Sync bounds on MappedMutexGuard.
The vulnerability resides in the futures-util crate prior to version 0.3.7. The MutexGuard::map function returns a MappedMutexGuard whose Send and Sync implementations only consider variance on the original type T, ignoring the mapped type U. This allows safe Rust code to send a MappedMutexGuard across threads even when U contains non-thread-safe types like Rc [1] [3].
Exploitation requires local access, low privileges, and high attack complexity. An attacker can craft a closure that maps a MutexGuard to a type containing a non-thread-safe resource (e.g., Rc). By racing clones of the guard across threads, they can trigger a data race on the reference count, leading to undefined behavior [3].
The impact is primarily a denial of service (availability) through memory corruption. The CVSS score is 4.7 (medium) with an availability impact of high [2]. No confidentiality or integrity impact is expected, but memory safety violations could potentially be leveraged further.
The issue is fixed in futures-util version 0.3.7. Users should update to the patched release. There is no known workaround other than avoiding the use of MutexGuard::map with closures that return non-thread-safe types [1].
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
futures-utilcrates.io | >= 0.3.2, < 0.3.7 | 0.3.7 |
Affected products
2- Rust/futures-utildescription
Patches
123 files changed · +75 −70
CHANGELOG.md+5 −0 modified@@ -1,3 +1,8 @@ +# 0.3.7 - 2020-10-23 +* Fixed unsoundness in `MappedMutexGuard` (#2240) +* Re-exported `TakeUntil` (#2235) +* futures-test: Prevent double panic in `panic_waker` (#2236) + # 0.3.6 - 2020-10-06 * Fixed UB due to missing 'static on `task::waker` (#2206) * Added `AsyncBufReadExt::fill_buf` (#2225)
examples/functional/Cargo.toml+3 −3 modified@@ -1,14 +1,14 @@ [package] name = "futures-example-functional" edition = "2018" -version = "0.3.6" +version = "0.3.7" authors = ["Alex Crichton <alex@alexcrichton.com>"] license = "MIT OR Apache-2.0" readme = "../README.md" keywords = ["futures", "async", "future"] repository = "https://github.com/rust-lang/futures-rs" homepage = "https://rust-lang.github.io/futures-rs" -documentation = "https://docs.rs/futures/0.3.6" +documentation = "https://docs.rs/futures/0.3.7" description = """ An implementation of futures and streams featuring zero allocations, composability, and iterator-like interfaces. @@ -17,4 +17,4 @@ categories = ["asynchronous"] publish = false [dependencies] -futures = { path = "../../futures", version = "0.3.6", features = ["thread-pool"] } +futures = { path = "../../futures", version = "0.3.7", features = ["thread-pool"] }
examples/imperative/Cargo.toml+3 −3 modified@@ -1,14 +1,14 @@ [package] name = "futures-example-imperative" edition = "2018" -version = "0.3.6" +version = "0.3.7" authors = ["Alex Crichton <alex@alexcrichton.com>"] license = "MIT OR Apache-2.0" readme = "../README.md" keywords = ["futures", "async", "future"] repository = "https://github.com/rust-lang/futures-rs" homepage = "https://rust-lang.github.io/futures-rs" -documentation = "https://docs.rs/futures/0.3.6" +documentation = "https://docs.rs/futures/0.3.7" description = """ An implementation of futures and streams featuring zero allocations, composability, and iterator-like interfaces. @@ -17,4 +17,4 @@ categories = ["asynchronous"] publish = false [dependencies] -futures = { path = "../../futures", version = "0.3.6", features = ["thread-pool"] } +futures = { path = "../../futures", version = "0.3.7", features = ["thread-pool"] }
futures/Cargo.toml+11 −11 modified@@ -1,14 +1,14 @@ [package] name = "futures" edition = "2018" -version = "0.3.6" +version = "0.3.7" authors = ["Alex Crichton <alex@alexcrichton.com>"] license = "MIT OR Apache-2.0" readme = "../README.md" keywords = ["futures", "async", "future"] repository = "https://github.com/rust-lang/futures-rs" homepage = "https://rust-lang.github.io/futures-rs" -documentation = "https://docs.rs/futures/0.3.6" +documentation = "https://docs.rs/futures/0.3.7" description = """ An implementation of futures and streams featuring zero allocations, composability, and iterator-like interfaces. @@ -19,18 +19,18 @@ categories = ["asynchronous"] travis-ci = { repository = "rust-lang/futures-rs" } [dependencies] -futures-core = { path = "../futures-core", version = "0.3.6", default-features = false } -futures-task = { path = "../futures-task", version = "0.3.6", default-features = false } -futures-channel = { path = "../futures-channel", version = "0.3.6", default-features = false, features = ["sink"] } -futures-executor = { path = "../futures-executor", version = "0.3.6", default-features = false, optional = true } -futures-io = { path = "../futures-io", version = "0.3.6", default-features = false } -futures-sink = { path = "../futures-sink", version = "0.3.6", default-features = false } -futures-util = { path = "../futures-util", version = "0.3.6", default-features = false, features = ["sink"] } +futures-core = { path = "../futures-core", version = "0.3.7", default-features = false } +futures-task = { path = "../futures-task", version = "0.3.7", default-features = false } +futures-channel = { path = "../futures-channel", version = "0.3.7", default-features = false, features = ["sink"] } +futures-executor = { path = "../futures-executor", version = "0.3.7", default-features = false, optional = true } +futures-io = { path = "../futures-io", version = "0.3.7", default-features = false } +futures-sink = { path = "../futures-sink", version = "0.3.7", default-features = false } +futures-util = { path = "../futures-util", version = "0.3.7", default-features = false, features = ["sink"] } [dev-dependencies] pin-utils = "0.1.0" -futures-executor = { path = "../futures-executor", version = "0.3.6", features = ["thread-pool"] } -futures-test = { path = "../futures-test", version = "0.3.6" } +futures-executor = { path = "../futures-executor", version = "0.3.7", features = ["thread-pool"] } +futures-test = { path = "../futures-test", version = "0.3.7" } tokio = "0.1.11" assert_matches = "1.3.0" pin-project = "1.0.1"
futures-channel/Cargo.toml+6 −6 modified@@ -1,12 +1,12 @@ [package] name = "futures-channel" edition = "2018" -version = "0.3.6" +version = "0.3.7" authors = ["Alex Crichton <alex@alexcrichton.com>"] license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/futures-rs" homepage = "https://rust-lang.github.io/futures-rs" -documentation = "https://docs.rs/futures-channel/0.3.6" +documentation = "https://docs.rs/futures-channel/0.3.7" description = """ Channels for asynchronous communication using futures-rs. """ @@ -24,12 +24,12 @@ unstable = ["futures-core/unstable"] cfg-target-has-atomic = ["futures-core/cfg-target-has-atomic"] [dependencies] -futures-core = { path = "../futures-core", version = "0.3.6", default-features = false } -futures-sink = { path = "../futures-sink", version = "0.3.6", default-features = false, optional = true } +futures-core = { path = "../futures-core", version = "0.3.7", default-features = false } +futures-sink = { path = "../futures-sink", version = "0.3.7", default-features = false, optional = true } [dev-dependencies] -futures = { path = "../futures", version = "0.3.6", default-features = true } -futures-test = { path = "../futures-test", version = "0.3.6", default-features = true } +futures = { path = "../futures", version = "0.3.7", default-features = true } +futures-test = { path = "../futures-test", version = "0.3.7", default-features = true } [package.metadata.docs.rs] all-features = true
futures-channel/src/lib.rs+1 −1 modified@@ -22,7 +22,7 @@ #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))] -#![doc(html_root_url = "https://docs.rs/futures-channel/0.3.6")] +#![doc(html_root_url = "https://docs.rs/futures-channel/0.3.7")] #[cfg(all(feature = "cfg-target-has-atomic", not(feature = "unstable")))] compile_error!("The `cfg-target-has-atomic` feature requires the `unstable` feature as an explicit opt-in to unstable features");
futures-core/Cargo.toml+3 −3 modified@@ -1,12 +1,12 @@ [package] name = "futures-core" edition = "2018" -version = "0.3.6" +version = "0.3.7" authors = ["Alex Crichton <alex@alexcrichton.com>"] license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/futures-rs" homepage = "https://rust-lang.github.io/futures-rs" -documentation = "https://docs.rs/futures-core/0.3.6" +documentation = "https://docs.rs/futures-core/0.3.7" description = """ The core traits and types in for the `futures` library. """ @@ -25,7 +25,7 @@ cfg-target-has-atomic = [] [dependencies] [dev-dependencies] -futures = { path = "../futures", version = "0.3.6" } +futures = { path = "../futures", version = "0.3.7" } [package.metadata.docs.rs] all-features = true
futures-core/src/lib.rs+1 −1 modified@@ -16,7 +16,7 @@ #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))] -#![doc(html_root_url = "https://docs.rs/futures-core/0.3.6")] +#![doc(html_root_url = "https://docs.rs/futures-core/0.3.7")] #[cfg(all(feature = "cfg-target-has-atomic", not(feature = "unstable")))] compile_error!("The `cfg-target-has-atomic` feature requires the `unstable` feature as an explicit opt-in to unstable features");
futures-executor/Cargo.toml+6 −6 modified@@ -1,12 +1,12 @@ [package] name = "futures-executor" edition = "2018" -version = "0.3.6" +version = "0.3.7" authors = ["Alex Crichton <alex@alexcrichton.com>"] license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/futures-rs" homepage = "https://rust-lang.github.io/futures-rs" -documentation = "https://docs.rs/futures-executor/0.3.6" +documentation = "https://docs.rs/futures-executor/0.3.7" description = """ Executors for asynchronous tasks based on the futures-rs library. """ @@ -17,13 +17,13 @@ std = ["futures-core/std", "futures-task/std", "futures-util/std"] thread-pool = ["std", "num_cpus"] [dependencies] -futures-core = { path = "../futures-core", version = "0.3.6", default-features = false } -futures-task = { path = "../futures-task", version = "0.3.6", default-features = false } -futures-util = { path = "../futures-util", version = "0.3.6", default-features = false } +futures-core = { path = "../futures-core", version = "0.3.7", default-features = false } +futures-task = { path = "../futures-task", version = "0.3.7", default-features = false } +futures-util = { path = "../futures-util", version = "0.3.7", default-features = false } num_cpus = { version = "1.8.0", optional = true } [dev-dependencies] -futures = { path = "../futures", version = "0.3.6" } +futures = { path = "../futures", version = "0.3.7" } [package.metadata.docs.rs] all-features = true
futures-executor/src/lib.rs+1 −1 modified@@ -17,7 +17,7 @@ #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))] -#![doc(html_root_url = "https://docs.rs/futures-executor/0.3.6")] +#![doc(html_root_url = "https://docs.rs/futures-executor/0.3.7")] #![cfg_attr(docsrs, feature(doc_cfg))]
futures-io/Cargo.toml+2 −2 modified@@ -1,12 +1,12 @@ [package] name = "futures-io" edition = "2018" -version = "0.3.6" +version = "0.3.7" authors = ["Alex Crichton <alex@alexcrichton.com>"] license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/futures-rs" homepage = "https://rust-lang.github.io/futures-rs" -documentation = "https://docs.rs/futures-io/0.3.6" +documentation = "https://docs.rs/futures-io/0.3.7" description = """ The `AsyncRead`, `AsyncWrite`, `AsyncSeek`, and `AsyncBufRead` traits for the futures-rs library. """
futures-io/src/lib.rs+1 −1 modified@@ -24,7 +24,7 @@ #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))] -#![doc(html_root_url = "https://docs.rs/futures-io/0.3.6")] +#![doc(html_root_url = "https://docs.rs/futures-io/0.3.7")] #![cfg_attr(docsrs, feature(doc_cfg))]
futures-macro/Cargo.toml+2 −2 modified@@ -1,12 +1,12 @@ [package] name = "futures-macro" edition = "2018" -version = "0.3.6" +version = "0.3.7" authors = ["Taylor Cramer <cramertj@google.com>", "Taiki Endo <te316e89@gmail.com>"] license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/futures-rs" homepage = "https://rust-lang.github.io/futures-rs" -documentation = "https://docs.rs/futures-macro/0.3.6" +documentation = "https://docs.rs/futures-macro/0.3.7" description = """ The futures-rs procedural macro implementations. """
futures-macro/src/lib.rs+1 −1 modified@@ -13,7 +13,7 @@ #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))] -#![doc(html_root_url = "https://docs.rs/futures-join-macro/0.3.6")] +#![doc(html_root_url = "https://docs.rs/futures-join-macro/0.3.7")] // Since https://github.com/rust-lang/cargo/pull/7700 `proc_macro` is part of the prelude for // proc-macro crates, but to support older compilers we still need this explicit `extern crate`.
futures-sink/Cargo.toml+2 −2 modified@@ -1,12 +1,12 @@ [package] name = "futures-sink" edition = "2018" -version = "0.3.6" +version = "0.3.7" authors = ["Alex Crichton <alex@alexcrichton.com>"] license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/futures-rs" homepage = "https://rust-lang.github.io/futures-rs" -documentation = "https://docs.rs/futures-sink/0.3.6" +documentation = "https://docs.rs/futures-sink/0.3.7" description = """ The asynchronous `Sink` trait for the futures-rs library. """
futures-sink/src/lib.rs+1 −1 modified@@ -16,7 +16,7 @@ #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))] -#![doc(html_root_url = "https://docs.rs/futures-sink/0.3.6")] +#![doc(html_root_url = "https://docs.rs/futures-sink/0.3.7")] #[cfg(feature = "alloc")] extern crate alloc;
futures/src/lib.rs+1 −1 modified@@ -95,7 +95,7 @@ #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))] -#![doc(html_root_url = "https://docs.rs/futures/0.3.6")] +#![doc(html_root_url = "https://docs.rs/futures/0.3.7")] #![cfg_attr(docsrs, feature(doc_cfg))]
futures-task/Cargo.toml+3 −3 modified@@ -1,12 +1,12 @@ [package] name = "futures-task" edition = "2018" -version = "0.3.6" +version = "0.3.7" authors = ["Alex Crichton <alex@alexcrichton.com>"] license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/futures-rs" homepage = "https://rust-lang.github.io/futures-rs" -documentation = "https://docs.rs/futures-task/0.3.6" +documentation = "https://docs.rs/futures-task/0.3.7" description = """ Tools for working with tasks. """ @@ -26,7 +26,7 @@ cfg-target-has-atomic = [] once_cell = { version = "1.3.1", default-features = false, features = ["std"], optional = true } [dev-dependencies] -futures = { path = "../futures", version = "0.3.6" } +futures = { path = "../futures", version = "0.3.7" } [package.metadata.docs.rs] all-features = true
futures-task/src/lib.rs+1 −1 modified@@ -16,7 +16,7 @@ #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))] -#![doc(html_root_url = "https://docs.rs/futures-task/0.3.6")] +#![doc(html_root_url = "https://docs.rs/futures-task/0.3.7")] #[cfg(all(feature = "cfg-target-has-atomic", not(feature = "unstable")))] compile_error!("The `cfg-target-has-atomic` feature requires the `unstable` feature as an explicit opt-in to unstable features");
futures-test/Cargo.toml+9 −9 modified@@ -1,29 +1,29 @@ [package] name = "futures-test" edition = "2018" -version = "0.3.6" +version = "0.3.7" authors = ["Wim Looman <wim@nemo157.com>"] license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/futures-rs" homepage = "https://rust-lang.github.io/futures-rs" -documentation = "https://docs.rs/futures-test/0.3.6" +documentation = "https://docs.rs/futures-test/0.3.7" description = """ Common utilities for testing components built off futures-rs. """ [dependencies] -futures-core = { version = "0.3.6", path = "../futures-core", default-features = false } -futures-task = { version = "0.3.6", path = "../futures-task", default-features = false } -futures-io = { version = "0.3.6", path = "../futures-io", default-features = false } -futures-util = { version = "0.3.6", path = "../futures-util", default-features = false } -futures-executor = { version = "0.3.6", path = "../futures-executor", default-features = false } -futures-sink = { version = "0.3.6", path = "../futures-sink", default-features = false } +futures-core = { version = "0.3.7", path = "../futures-core", default-features = false } +futures-task = { version = "0.3.7", path = "../futures-task", default-features = false } +futures-io = { version = "0.3.7", path = "../futures-io", default-features = false } +futures-util = { version = "0.3.7", path = "../futures-util", default-features = false } +futures-executor = { version = "0.3.7", path = "../futures-executor", default-features = false } +futures-sink = { version = "0.3.7", path = "../futures-sink", default-features = false } pin-utils = { version = "0.1.0", default-features = false } once_cell = { version = "1.3.1", default-features = false, features = ["std"], optional = true } pin-project = "1.0.1" [dev-dependencies] -futures = { version = "0.3.6", path = "../futures", default-features = false, features = ["std", "executor"] } +futures = { version = "0.3.7", path = "../futures", default-features = false, features = ["std", "executor"] } [features] default = ["std"]
futures-test/src/lib.rs+1 −1 modified@@ -12,7 +12,7 @@ #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))] -#![doc(html_root_url = "https://docs.rs/futures-test/0.3.6")] +#![doc(html_root_url = "https://docs.rs/futures-test/0.3.7")] #[cfg(not(feature = "std"))] compile_error!("`futures-test` must have the `std` feature activated, this is a default-active feature");
futures-util/Cargo.toml+10 −10 modified@@ -1,12 +1,12 @@ [package] name = "futures-util" edition = "2018" -version = "0.3.6" +version = "0.3.7" authors = ["Alex Crichton <alex@alexcrichton.com>"] license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/futures-rs" homepage = "https://rust-lang.github.io/futures-rs" -documentation = "https://docs.rs/futures-util/0.3.6" +documentation = "https://docs.rs/futures-util/0.3.7" description = """ Common utilities and extension traits for the futures-rs library. """ @@ -33,12 +33,12 @@ read-initializer = ["io", "futures-io/read-initializer", "futures-io/unstable"] write-all-vectored = ["io"] [dependencies] -futures-core = { path = "../futures-core", version = "0.3.6", default-features = false } -futures-task = { path = "../futures-task", version = "0.3.6", default-features = false } -futures-channel = { path = "../futures-channel", version = "0.3.6", default-features = false, features = ["std"], optional = true } -futures-io = { path = "../futures-io", version = "0.3.6", default-features = false, features = ["std"], optional = true } -futures-sink = { path = "../futures-sink", version = "0.3.6", default-features = false, optional = true } -futures-macro = { path = "../futures-macro", version = "=0.3.6", default-features = false, optional = true } +futures-core = { path = "../futures-core", version = "0.3.7", default-features = false } +futures-task = { path = "../futures-task", version = "0.3.7", default-features = false } +futures-channel = { path = "../futures-channel", version = "0.3.7", default-features = false, features = ["std"], optional = true } +futures-io = { path = "../futures-io", version = "0.3.7", default-features = false, features = ["std"], optional = true } +futures-sink = { path = "../futures-sink", version = "0.3.7", default-features = false, optional = true } +futures-macro = { path = "../futures-macro", version = "=0.3.7", default-features = false, optional = true } proc-macro-hack = { version = "0.5.9", optional = true } proc-macro-nested = { version = "0.1.2", optional = true } slab = { version = "0.4.2", optional = true } @@ -49,8 +49,8 @@ pin-utils = "0.1.0" pin-project = "1.0.1" [dev-dependencies] -futures = { path = "../futures", version = "0.3.6", features = ["async-await", "thread-pool"] } -futures-test = { path = "../futures-test", version = "0.3.6" } +futures = { path = "../futures", version = "0.3.7", features = ["async-await", "thread-pool"] } +futures-test = { path = "../futures-test", version = "0.3.7" } tokio = "0.1.11" [package.metadata.docs.rs]
futures-util/src/lib.rs+1 −1 modified@@ -18,7 +18,7 @@ #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))] -#![doc(html_root_url = "https://docs.rs/futures-util/0.3.6")] +#![doc(html_root_url = "https://docs.rs/futures-util/0.3.7")] #![cfg_attr(docsrs, feature(doc_cfg))]
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-rh4w-94hh-9943ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-35905ghsaADVISORY
- github.com/rust-lang/futures-rs/issues/2239ghsaWEB
- rustsec.org/advisories/RUSTSEC-2020-0059.htmlghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.