From: Yuxuan Shui yshui@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,