VYPR
High severityNVD Advisory· Published Sep 25, 2019· Updated Aug 5, 2024

CVE-2019-16882

CVE-2019-16882

Description

A use-after-free vulnerability in the string-interner Rust crate allows attackers to read memory via dangling pointers due to a flawed clone implementation.

AI Insight

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

A use-after-free vulnerability in the string-interner Rust crate allows attackers to read memory via dangling pointers due to a flawed clone implementation.

Vulnerability

Description

The string-interner crate before version 0.7.1 for Rust contains a use-after-free vulnerability arising from a flawed Clone implementation [1]. When an interner is cloned, the derived #[derive(Clone)] macro did not properly duplicate the underlying string storage, causing the cloned interner to retain InternalStrRef pointers that referenced the original interner's memory [2]. After the original interner is dropped, those pointers become dangling, leading to undefined behavior [3].

Exploitation

An attacker can trigger this vulnerability by cloning a StringInterner and then dropping the original instance, leaving the clone with dangling references [2]. No special privileges or user interaction are required; the attack vector is network-based with low complexity [3]. The flaw is exploitable in any application that uses the affected crate version and performs clone-and-drop operations on interners.

Impact

Successful exploitation allows an attacker to read from memory locations that were previously occupied by interned strings, potentially leaking sensitive data [1]. The confidentiality impact is high, while integrity and availability are not affected [3]. The vulnerability is classified as CWE-416 (Use After Free) and has a CVSS v3.1 base score of 7.5 (HIGH) [3].

Mitigation

The issue was fixed in commit d91dac0, which manually implements Clone for StringInterner to recreate the internal HashMap with fresh InternalStrRef pointers pointing to newly cloned strings [4]. Patched versions are 0.6.4 and 0.7.1 [3]. Users should update to these or later versions. No workarounds are documented.

AI Insight generated on May 22, 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
string-internercrates.io
>= 0.7.0, < 0.7.10.7.1
string-internercrates.io
< 0.6.40.6.4

Affected products

2

Patches

1
d91dac0cfe42

Fix use after free bug around `StringInterner::clone()` (#10)

https://github.com/Robbepop/string-internerYOSHIOKA TakumaAug 25, 2019via ghsa
2 files changed · +63 1
  • src/lib.rs+23 1 modified
    @@ -192,7 +192,7 @@ pub type DefaultStringInterner = StringInterner<Sym>;
     
     /// Caches strings efficiently, with minimal memory footprint and associates them with unique symbols.
     /// These symbols allow constant time comparisons and look-ups to the underlying interned strings.
    -#[derive(Debug, Clone, Eq)]
    +#[derive(Debug, Eq)]
     pub struct StringInterner<S, H = RandomState>
     where
     	S: Symbol,
    @@ -219,6 +219,28 @@ impl Default for StringInterner<Sym, RandomState> {
     	}
     }
     
    +// Should be manually cloned.
    +// See <https://github.com/Robbepop/string-interner/issues/9>.
    +impl<S, H> Clone for StringInterner<S, H>
    +where
    +	S: Symbol,
    +	H: Clone + BuildHasher,
    +{
    +	fn clone(&self) -> Self {
    +		let values = self.values.clone();
    +		let mut map = HashMap::with_capacity_and_hasher(values.len(), self.map.hasher().clone());
    +		// Recreate `InternalStrRef` from the newly cloned `Box<str>`s.
    +		// Use `extend()` to avoid `H: Default` trait bound required by `FromIterator for HashMap`.
    +		map.extend(
    +			values
    +			.iter()
    +			.enumerate()
    +			.map(|(i, s)| (InternalStrRef::from_str(s), S::from_usize(i))),
    +		);
    +		Self { values, map }
    +	}
    +}
    +
     // About `Send` and `Sync` impls for `StringInterner`
     // --------------------------------------------------
     //
    
  • src/tests.rs+40 0 modified
    @@ -373,3 +373,43 @@ mod from_iterator {
     		);
     	}
     }
    +
    +// See <https://github.com/Robbepop/string-interner/issues/9>.
    +mod clone_and_drop {
    +	use super::*;
    +
    +	fn clone_and_drop() -> (DefaultStringInterner, Sym) {
    +		let mut old = DefaultStringInterner::new();
    +		let foo = old.get_or_intern("foo");
    +
    +		// Return newly created (cloned) interner, and drop the original `old` itself.
    +		(old.clone(), foo)
    +	}
    +
    +	#[test]
    +	fn no_use_after_free() {
    +		let (mut new, foo) = clone_and_drop();
    +
    +		// This assert may fail if there are use after free bug.
    +		// See <https://github.com/Robbepop/string-interner/issues/9> for detail.
    +		assert_eq!(
    +			new.get_or_intern("foo"),
    +			foo,
    +			"`foo` should represent the string \"foo\" so they should be equal"
    +		);
    +	}
    +
    +	#[test]
    +	// Test for new (non-`derive`) `Clone` impl.
    +	fn clone() {
    +		let mut old = DefaultStringInterner::new();
    +		let strings = &["foo", "bar", "baz", "qux", "quux", "corge"];
    +		let syms = strings.iter().map(|&s| old.get_or_intern(s)).collect::<Vec<_>>();
    +
    +		let mut new = old.clone();
    +		for (&s, &sym) in strings.iter().zip(&syms) {
    +			assert_eq!(new.resolve(sym), Some(s));
    +			assert_eq!(new.get_or_intern(s), sym);
    +		}
    +	}
    +}
    

Vulnerability mechanics

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

References

6

News mentions

0

No linked articles in our index yet.