Skip to content

Fix double free when a comparator panics mid-split_off - #160901

Closed
sankalpsthakur wants to merge 1 commit into
rust-lang:mainfrom
sankalpsthakur:fix-158165-btree-split-off-panic-safety
Closed

Fix double free when a comparator panics mid-split_off#160901
sankalpsthakur wants to merge 1 commit into
rust-lang:mainfrom
sankalpsthakur:fix-158165-btree-split-off-panic-safety

Conversation

@sankalpsthakur

@sankalpsthakur sankalpsthakur commented Aug 11, 2026

Copy link
Copy Markdown

Summary

Revives the approach from closed #158710 for #158165 (I-unsound / P-high).

Root::split_off's loop calls search_node (which invokes the caller's Ord/Borrow impl and can panic) interleaved with move_suffix, which physically relocates key-value pairs out of the left tree and into the new right-hand tree one level at a time. If the comparator panics on a level after the first move_suffix has already run, the unwind leaves self with its old, too-large length but a tree that's missing whatever already got moved into right_root — and right_root itself gets dropped along with the panic, freeing those values. Iterating or dropping the "recovered" map afterwards walks past the border into node slots that no longer own what they claim to, and double frees.

search_node is pure — it's the only thing here that can fail, and nothing gets mutated until move_suffix runs — so a drop guard that only gets armed once the first move actually happens turns the panic into a clean abort instead. This matches the panic-safety strategy mem::replace already uses in btree/mem.rs.

Uses get_or_insert_with (not get_or_insert): the latter takes its argument by value, so on every loop iteration after the first it would construct a fresh AbortOnDrop, find the Option already Some, and immediately drop (and thus abort on) the throwaway one.

Adds a regression test that ordinary multi-level (non-panicking) splits still work with the guard armed across levels. The abort path itself cannot be observed from within a single process; see the issue reproducer for the double-free.

Validation

Fixes #158165

AI/LLM disclosure

  • AI coding tools (including Grok and/or Codex agent-assisted editing) were used to help draft or modify code and this PR description.
  • I reviewed the complete change, understand the reasoning, and ran the reported local tests before submitting.
  • This submission is original work of authorship under the project CLA / contributor terms; AI output was not pasted unreviewed.

Made with Cursor

Root::split_off interleaves Ord-invoking search_node with move_suffix.
If the comparator panics after the first move, unwind left trees in an
inconsistent state that double-frees on drop. Abort after the first
move_suffix instead, matching the panic-safety pattern in btree/mem.rs.

Fixes rust-lang#158165

Signed-off-by: Sankalp Thakur <sankalphimself@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 11, 2026
@rustbot

rustbot commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome! The Rust Project is excited to review your changes, and you should hear from @clarfonthey (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue
Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: libs
  • libs expanded to 12 candidates
  • Random selection from JohnTitor, Mark-Simulacrum, clarfonthey, nia-e

@rustbot

rustbot commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

⚠️ Warning ⚠️

  • There are issue links (such as #123) in the commit messages of the following commits.
    Please move them to the PR description, to avoid spamming the issues with references to the commit, and so this bot can automatically canonicalize them to avoid issues with subtree.

@oli-obk

oli-obk commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

#160903 (comment)

@oli-obk oli-obk closed this Aug 11, 2026
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BTreeMap::split_off is not panic-safe leading to a potential double-free

4 participants