[PATCH v2 0/1] MR3955: mf: Avoid a double free of presentation clock timers.
In clock_change_state() when a clock is running, a timer is removed from clock->timers. The same timer is then used to create an async result, which will eventually calls present_clock_timer_callback_Invoke() and removes the same timer. -- v2: mf: Avoid a double free of presentation clock timers. https://gitlab.winehq.org/wine/wine/-/merge_requests/3955
From: Zhiyi Zhang <zzhang(a)codeweavers.com> In clock_change_state() when a clock is running, a timer is removed from clock->timers. The same timer is then used to create an async result, which will eventually calls present_clock_timer_callback_Invoke() and release the same timer. This patch checks if the timer is still in clock->timers before releasing it. --- dlls/mf/clock.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/dlls/mf/clock.c b/dlls/mf/clock.c index aef4366c6d9..e6be05d2794 100644 --- a/dlls/mf/clock.c +++ b/dlls/mf/clock.c @@ -1108,13 +1108,19 @@ static HRESULT WINAPI present_clock_timer_callback_Invoke(IMFAsyncCallback *ifac if (FAILED(hr = IMFAsyncResult_GetObject(result, &object))) return hr; - timer = impl_clock_timer_from_IUnknown(object); - EnterCriticalSection(&clock->cs); - list_remove(&timer->entry); - IUnknown_Release(&timer->IUnknown_iface); + LIST_FOR_EACH_ENTRY(timer, &clock->timers, struct clock_timer, entry) + { + if (&timer->IUnknown_iface == object) + { + list_remove(&timer->entry); + IUnknown_Release(&timer->IUnknown_iface); + break; + } + } LeaveCriticalSection(&clock->cs); + timer = impl_clock_timer_from_IUnknown(object); IMFAsyncCallback_Invoke(timer->callback, timer->result); IUnknown_Release(object); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/3955
v2: Check if a timer is still in clock->timers before releasing it in present_clock_timer_callback_Invoke(). -- https://gitlab.winehq.org/wine/wine/-/merge_requests/3955#note_46913
On Mon Oct 9 14:34:28 2023 +0000, Zhiyi Zhang wrote:
v2: Check if a timer is still in clock->timers before releasing it in present_clock_timer_callback_Invoke(). Thanks, we could try to unify that later with CancelTimer(), but it's good as is.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/3955#note_48022
This merge request was approved by Nikolay Sivov. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/3955
participants (3)
-
Nikolay Sivov (@nsivov) -
Zhiyi Zhang -
Zhiyi Zhang (@zhiyi)