From 39fe7e889308dd0df05f1b3e3a550769b873588a Mon Sep 17 00:00:00 2001 From: tooson9010-spec Date: Thu, 8 Oct 2026 16:01:36 +0900 Subject: [PATCH] Add advisory for hecs: double free when a component's Drop panics --- crates/hecs/RUSTSEC-0000-0000.md | 41 ++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 crates/hecs/RUSTSEC-0000-0000.md diff --git a/crates/hecs/RUSTSEC-0000-0000.md b/crates/hecs/RUSTSEC-0000-0000.md new file mode 100644 index 000000000..a069f1b4c --- /dev/null +++ b/crates/hecs/RUSTSEC-0000-0000.md @@ -0,0 +1,41 @@ +```toml +[advisory] +id = "RUSTSEC-0000-0000" +package = "hecs" +date = "2026-10-08" +url = "https://github.com/Ralith/hecs/pull/471" +categories = ["memory-corruption"] +keywords = ["memory-safety", "double-free", "panic-safety"] + +[affected.functions] +"hecs::World::clear" = ["< 0.11.2"] +"hecs::World::despawn" = ["< 0.11.2"] +"hecs::World::spawn_at" = ["< 0.11.2"] +"hecs::World::spawn_column_batch_at" = ["< 0.11.2"] +"hecs::CommandBuffer::run_on" = ["< 0.11.2"] + +[versions] +patched = [">= 0.11.2"] +``` + +# Double free when a component's `Drop` panics + +Several `hecs` operations run component destructors before committing the +bookkeeping that records which slots hold live components. If a destructor +unwinds, that commit is skipped and the already-dropped slots are still treated +as live, so a later `Drop for Archetype` or a subsequent operation destroys them +a second time — a double free (CWE-415) reachable from safe Rust. Storing a +component whose `Drop` panics is enough. + +- `Archetype::clear` does not reset the length before running destructors, and + `Archetype::remove` does not commit the length before the move. Reached from + `World::clear`, `World::despawn`, `World::spawn_at` and + `World::spawn_column_batch_at`. +- `CommandBuffer::run_on` skips `components.clear()` on unwind, so the buffer + drops components the `World` now owns. + +`Archetype::remove` also copies the last component into the removed slot before +committing, so an unwind leaves the same value live in two slots and both are +dropped. + +Confirmed with AddressSanitizer on 0.11.1.