Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potential pointer use after free in current lock-free mpsc queue #1

Open
zyounan opened this issue Jul 27, 2021 · 0 comments
Open

Potential pointer use after free in current lock-free mpsc queue #1

zyounan opened this issue Jul 27, 2021 · 0 comments

Comments

@zyounan
Copy link

zyounan commented Jul 27, 2021

The following code comes from 7ab32b4

template<typename T>
void MpscQueue<T>::enqueue(const T &input) {
    BufferNode *node{new BufferNode(input)};  // #1
    BufferNode *prevhead{head_.exchange(node, std::memory_order_acq_rel)};      // #2
    prevhead->next_.store(node, std::memory_order_release);  // #3
}

template<typename T>
bool MpscQueue<T>::dequeue(T &output) {
    BufferNode *tail = tail_.load(std::memory_order_relaxed);
    BufferNode *next = tail->next_.load(std::memory_order_acquire);

    if (next == nullptr) {
        return false;
    }
    output = std::move(*(next->dataPtr_));
    delete next->dataPtr_;    // #4
    tail_.store(next, std::memory_order_release);   // #5
    delete tail;
    return true;
}

Consider that 4 threads A, B, C, D. Assume that we have the queue with 3 elements and thread A is putting a new element 4 into the queue, in which case it's running in enqueue. After A executes #2 successfully, the current state of the queue looks like this:

                |---------------------- head
1 -> 2 -> 3 --> 4
          ^
          |------------------ prev

Assume that A is switched out by scheduler. Now thread B, C, D are trying to dequeue elements from the queue. They run to #4 and delete 1, 2, 3 respectively.
Note that current state of prev is freed and no longer valid. However, if A resumes at #3, the prevhead is actually deleted by other threads and it's UB now.

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

No branches or pull requests

1 participant