VYPR
Critical severityNVD Advisory· Published Mar 5, 2021· Updated Aug 3, 2024

CVE-2021-28032

CVE-2021-28032

Description

In the nano_arena Rust crate before 0.5.2, the split_at function can create multiple mutable references to the same element via a malicious Borrow implementation, leading to memory corruption.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

In the nano_arena Rust crate before 0.5.2, the split_at function can create multiple mutable references to the same element via a malicious Borrow implementation, leading to memory corruption.

Vulnerability

Description

The vulnerability resides in the split_at method of the nano_arena crate (versions prior to 0.5.2). The function calls selected.borrow() twice: once to obtain a mutable reference to an element and once to create the arena split. If the Borrow implementation does not return the same index on each call, this can result in two mutable references pointing to the same memory location, violating Rust's aliasing rules [1][2]. This is a soundness issue that allows undefined behavior.

Exploitation

An attacker can craft a custom type implementing Borrow that alternates between two different indices on successive calls. As demonstrated in the advisory, this can be used to obtain two mutable references to the same element, enabling out-of-bounds writes or use-after-free conditions [4]. The attack requires no special privileges and can be triggered remotely if the vulnerable code is used with untrusted input, as the CVSS vector indicates network attack vector with low complexity [2].

Impact

Successful exploitation can lead to memory corruption, potentially allowing arbitrary code execution, data exfiltration, or denial of service. The CVSS base score is 9.8 (Critical) with impacts on confidentiality, integrity, and availability [2].

Mitigation

The issue is patched in version 0.5.2 of the crate. Users should update immediately. There is no known workaround, as the vulnerability stems from the crate's API design [1][2].

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.

PackageAffected versionsPatched versions
nano_arenacrates.io
< 0.5.20.5.2

Affected products

2

Patches

1
6b83f9d07083

Fix #1, add tests

https://github.com/bennetthardwick/nano-arenaBennett HardwickMar 2, 2021via ghsa
1 file changed · +55 2
  • src/lib.rs+55 2 modified
    @@ -224,11 +224,13 @@ impl<T> Arena<T> {
             &'a mut self,
             selected: I,
         ) -> Option<(&mut T, ArenaSplit<'a, T>)> {
    -        if let Some(value) = self.get_mut(selected.borrow()) {
    +        let selected = selected.borrow();
    +
    +        if let Some(value) = self.get_mut(selected) {
                 Some((
                     unsafe { (value as *mut T).as_mut().unwrap() },
                     ArenaSplit {
    -                    selected: selected.borrow().clone(),
    +                    selected: selected.clone(),
                         arena: self,
                         __type: Default::default(),
                     },
    @@ -421,6 +423,7 @@ impl<T> Into<Vec<T>> for Arena<T> {
     #[cfg(test)]
     mod tests {
         use super::*;
    +    use std::cell::Cell;
     
         fn setup_arena() -> (Arena<String>, Idx, Idx, Idx, Idx) {
             let mut arena = Arena::new();
    @@ -707,4 +710,54 @@ mod tests {
     
             assert_eq!(format!("{:?}", john), "Removed Idx ( 0 )");
         }
    +
    +    #[test]
    +    fn compare_should_work_for_idx() {
    +        let mut arena = Arena::new();
    +        let left = arena.alloc(1);
    +        let right = left.clone();
    +
    +        assert!(left.borrow() == right.borrow());
    +    }
    +
    +    #[test]
    +    fn splitting_should_be_safe() {
    +        // A bug described here (https://github.com/bennetthardwick/nano-arena/issues/1) meant that
    +        // multiple mutable references could be handed out.
    +
    +        struct ToggleIdx {
    +            first: Idx,
    +            second: Idx,
    +            state: Cell<bool>,
    +        }
    +
    +        impl Borrow<Idx> for ToggleIdx {
    +            fn borrow(&self) -> &Idx {
    +                self.state.set(!self.state.get());
    +
    +                if self.state.get() {
    +                    &self.first
    +                } else {
    +                    &self.second
    +                }
    +            }
    +        }
    +
    +        let mut arena = Arena::new();
    +
    +        let first = arena.alloc(1);
    +        let second = arena.alloc(2);
    +
    +        let toggle_idx = ToggleIdx {
    +            first: first.clone(),
    +            second: second.clone(),
    +            state: Cell::new(false),
    +        };
    +
    +        let (first_mut_ref, mut split_arena) = arena.split_at(toggle_idx).unwrap();
    +        let second_mut_ref = split_arena.get_mut(&first);
    +
    +        drop(first_mut_ref);
    +        assert!(second_mut_ref.is_none());
    +    }
     }
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.