Skip to content

Commit

Permalink
Merge #466
Browse files Browse the repository at this point in the history
466: fix use-after-free in crossbeam-epoch/sync/queue r=jeehoonkang a=tomtomjhj

`pop()` must completely unlink the popped node from the shared memory before it calls `defer_destroy()` to prevent use-after-free. This implementation is based on the variation by Doherty et al. where the `head == tail` check is done after a successful CAS, which can be slightly more efficient than the original MSQueue.

closes #238

Co-authored-by: Jaehwang Jerry Jung <tomtomjhj@gmail.com>
  • Loading branch information
bors[bot] and tomtomjhj authored Feb 10, 2020
2 parents ebecb82 + 2618830 commit 0e91b78
Showing 1 changed file with 13 additions and 0 deletions.
13 changes: 13 additions & 0 deletions crossbeam-epoch/src/sync/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
//!
//! Michael and Scott. Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue
//! Algorithms. PODC 1996. http://dl.acm.org/citation.cfm?id=248106
//!
//! Simon Doherty, Lindsay Groves, Victor Luchangco, and Mark Moir. 2004b. Formal Verification of a
//! Practical Lock-Free Queue Algorithm. https://doi.org/10.1007/978-3-540-30232-2_7
use core::mem::{self, ManuallyDrop};
use core::ptr;
Expand Down Expand Up @@ -117,6 +120,11 @@ impl<T> Queue<T> {
self.head
.compare_and_set(head, next, Release, guard)
.map(|_| {
let tail = self.tail.load(Relaxed, guard);
// Advance the tail so that we don't retire a pointer to a reachable node.
if head == tail {
let _ = self.tail.compare_and_set(tail, next, Release, guard);
}
guard.defer_destroy(head);
Some(ManuallyDrop::into_inner(ptr::read(&n.data)))
})
Expand All @@ -142,6 +150,11 @@ impl<T> Queue<T> {
self.head
.compare_and_set(head, next, Release, guard)
.map(|_| {
let tail = self.tail.load(Relaxed, guard);
// Advance the tail so that we don't retire a pointer to a reachable node.
if head == tail {
let _ = self.tail.compare_and_set(tail, next, Release, guard);
}
guard.defer_destroy(head);
Some(ManuallyDrop::into_inner(ptr::read(&n.data)))
})
Expand Down

0 comments on commit 0e91b78

Please sign in to comment.