[2/2] strmbase: Destroy base class after child class.

Thomas Faber thomas.faber at reactos.org
Sat Jul 19 02:49:19 CDT 2014


This fixes a use-after-free:
The destruction code in BaseRendererImpl_Release calls several methods
of the input pin's IPin interface (e.g. IPin_ConnectedTo), and the
pin's pCritSec is set to &This->filter.csFilter (by BaseRenderer_Init).
This means calling BaseFilterImpl_Release deletes that critical section
before pInputPin is done with it.

This patch fixes it the way a C++ destructor would by calling the
parent destructor at the end.

There are several more occurrences of this pattern for BaseFilter
outside of strmbase that I plan to address next, pending any comments
or suggested changes here.
-------------- next part --------------
From c56d8040156aa51b28150838dc7540972c8f5bd8 Mon Sep 17 00:00:00 2001
From: Thomas Faber <thomas.faber at reactos.org>
Date: Fri, 18 Jul 2014 22:23:36 +0200
Subject: strmbase: Destroy base class after child class.

---
 dlls/strmbase/renderer.c  | 3 ++-
 dlls/strmbase/transform.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c
index bb91236..766e467 100644
--- a/dlls/strmbase/renderer.c
+++ b/dlls/strmbase/renderer.c
@@ -294,7 +294,7 @@ HRESULT WINAPI BaseRendererImpl_QueryInterface(IBaseFilter* iface, REFIID riid,
 ULONG WINAPI BaseRendererImpl_Release(IBaseFilter* iface)
 {
     BaseRenderer *This = impl_from_IBaseFilter(iface);
-    ULONG refCount = BaseFilterImpl_Release(iface);
+    ULONG refCount = InterlockedDecrement(&This->filter.refCount);
 
     if (!refCount)
     {
@@ -319,6 +319,7 @@ ULONG WINAPI BaseRendererImpl_Release(IBaseFilter* iface)
         CloseHandle(This->ThreadSignal);
         CloseHandle(This->RenderEvent);
         QualityControlImpl_Destroy(This->qcimpl);
+        BaseFilter_Destroy(&This->filter);
     }
     return refCount;
 }
diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index eba7ad2..0fc7515 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -313,7 +313,7 @@ HRESULT WINAPI TransformFilterImpl_QueryInterface(IBaseFilter * iface, REFIID ri
 ULONG WINAPI TransformFilterImpl_Release(IBaseFilter * iface)
 {
     TransformFilter *This = impl_from_IBaseFilter(iface);
-    ULONG refCount = BaseFilterImpl_Release(iface);
+    ULONG refCount = InterlockedDecrement(&This->filter.refCount);
 
     TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1);
 
@@ -343,6 +343,7 @@ ULONG WINAPI TransformFilterImpl_Release(IBaseFilter * iface)
         FreeMediaType(&This->pmt);
         QualityControlImpl_Destroy(This->qcimpl);
         IUnknown_Release(This->seekthru_unk);
+        BaseFilter_Destroy(&This->filter);
         CoTaskMemFree(This);
 
         return 0;
-- 
1.9.0.msysgit.0



More information about the wine-patches mailing list