Skip to content

Commit 5b1acd9

Browse files
committed
sync::mpsc: prevent double free on Drop
This PR is fixing a regression introduced by rust-lang#121646 that can lead to a double free when dropping the channel. The details of the bug can be found in the corresponding crossbeam PR crossbeam-rs/crossbeam#1187 Signed-off-by: Petros Angelatos <[email protected]>
1 parent 17c68d1 commit 5b1acd9

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

Diff for: std/src/sync/mpmc/list.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -569,9 +569,15 @@ impl<T> Channel<T> {
569569
// In that case, just wait until it gets initialized.
570570
while block.is_null() {
571571
backoff.spin_heavy();
572-
block = self.head.block.load(Ordering::Acquire);
572+
block = self.head.block.swap(ptr::null_mut(), Ordering::AcqRel);
573573
}
574574
}
575+
// After this point `head.block` is not modified again and it will be deallocated if it's
576+
// non-null. The `Drop` code of the channel, which runs after this function, also attempts
577+
// to deallocate `head.block` if it's non-null. Therefore this function must maintain the
578+
// invariant that if a deallocation of head.block is attemped then it must also be set to
579+
// NULL. Failing to do so will lead to the Drop code attempting a double free. For this
580+
// reason both reads above do an atomic swap instead of a simple atomic load.
575581

576582
unsafe {
577583
// Drop all messages between head and tail and deallocate the heap-allocated blocks.

0 commit comments

Comments
 (0)