-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Description
Context
The BinaryHeap
from alloc
crate has handy method peek_mut
, which allows to look at the top element in the heap, and possible mutate it, without removing it from the heap. This mutation however can alter the element order relative to other elements, and the heap needs to be adjusted. To handle this, the PeekMut
tracks if it has ever exposed a &mut T
access via DerefMut
. If &mut T
was ever exposed, PeekMut
adjusts the heap in its Drop implementation.
Leak amplification
This works well, unless the user leaks the PeekMut(e.g. via mem::forget, or via Rc cycle). Then the Drop of PeekMut never runs and we get the heap with an incorrect ordering of elements.
To cope with this possible leakage, the PeekMut uses a well-known technique called "leak amplification". That is, PeekMut
uses Vec::set_len
to forget about all other elements in the heap, when first &mut T
is acquired, and then restores vector len when drop is run. So if the user leaks the PeekMut, we still have the valid heap (although, it has only 1 element - all others were forgotten forever).
This change was introduced in commit aedb756.
Problem
The "leak amplification" technique is inteded to avoid memory corruption. It is often used when the type creates temporary holes in the container. Thus, forgetting to fixup those holes might lead to double free, or use after free. In other words, leak amplification is used to make the code sound, not to make it logically correct.
However BinaryHeap
soundness does not depend on correctness of element ordering. BinaryHeap
will continue to be sound(that is no memory issues), even the elements in the underlying vector get shuffled in arbitrary way. This is easy to see, as there can be an incorrect Ord
implementation; or users can use interior mutability to break the heap ordering.
The data structure will not work logically correct in such case, but it is the question of which correctness property we are willing to sacrafice: ordering of the elements or elements leakage.
Proposal
I propose to rollback the before mentioned commit and ignore the leakage problem in the PeekMut.