Skip to content

Fix panic-safety unsoundness in SmallMap::retain (use-after-free when an element's Drop panics) - #10

Merged
ihciah merged 1 commit into
ihciah:masterfrom
tooson9010-spec:fix-retain-panic-safety
Aug 9, 2026
Merged

Fix panic-safety unsoundness in SmallMap::retain (use-after-free when an element's Drop panics)#10
ihciah merged 1 commit into
ihciah:masterfrom
tooson9010-spec:fix-retain-panic-safety

Conversation

@tooson9010-spec

Copy link
Copy Markdown

Summary

RawInline::retain (reached via SmallMap::retain on an inline map) is not
panic-safe. It drop_in_places a rejected entry and only then calls erase to do
the swap-delete and decrement len:

core::ptr::drop_in_place(self.data[i].as_mut_ptr()); // may panic
self.erase(i);                                        // skipped on panic

If the entry's Drop panics, erase never runs, so len still counts the
already-dropped slot. When the map is later dropped, drop_elements walks 0..len
and drops that slot again — a double-free (CWE-415) / use-after-free (CWE-416)
reachable from safe Rust. This is a soundness issue.

Fix

Read the rejected entry out of the slot with ptr::read, run erase (swap-delete +
len decrement), and only then drop it. Once the entry has been moved out and the
structure is consistent, a panicking Drop can no longer leave a slot that
drop_elements would revisit.

Testing

Added retain_panicking_drop_keeps_map_consistent: an element whose Drop panics is
removed under catch_unwind, then the map is dropped. Under AddressSanitizer
(-Zsanitizer=address), the original code reports a heap-use-after-free on this
test; with the fix the test passes. The full existing test suite also still passes.

Disclosure

Found while researching panic-safety in Rust crates. Confirmed on 0.1.5.

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@ihciah ihciah left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@ihciah
ihciah merged commit 906c42a into ihciah:master Aug 9, 2026
12 checks passed
@tooson9010-spec

Copy link
Copy Markdown
Author

@ihciah Thanks for merging! Once this is released, I'd like to file a RustSec advisory so users still on 0.1.5 are notified. Would that be alright with you?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants