From: Yuxuan Shui <yshui(a)codeweavers.com> queue_release_pending_item releases the work_item reference but later accesses `item->queue`, which is a potential use-after-free. --- dlls/rtworkq/queue.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dlls/rtworkq/queue.c b/dlls/rtworkq/queue.c index 15b8da47639..27d715a9bf9 100644 --- a/dlls/rtworkq/queue.c +++ b/dlls/rtworkq/queue.c @@ -732,14 +732,18 @@ static HRESULT invoke_async_callback(IRtwqAsyncResult *result) static void queue_release_pending_item(struct work_item *item) { + BOOL should_release = FALSE; EnterCriticalSection(&item->queue->cs); if (item->key) { list_remove(&item->entry); item->key = 0; - IUnknown_Release(&item->IUnknown_iface); + should_release = TRUE; } LeaveCriticalSection(&item->queue->cs); + + if (should_release) + IUnknown_Release(&item->IUnknown_iface); } static void CALLBACK waiting_item_callback(TP_CALLBACK_INSTANCE *instance, void *context, TP_WAIT *wait, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/4243