[MPlayer-dev-eng] [PATCH] fix potential bug in loader/dshow/outputpin.c

Vladimir Voroshilov voroshil at gmail.com
Sat Feb 10 10:13:06 CET 2007


Hi, All.

DirectShow AM_MEDIA_TYPE structure has pbFormat pointer to additional
media type's data.

1. Some methods does copying of this structure without copying
additional data, pointed by pbFormat. As result two structures will
point to the same block of additional data.
Freeing original and copyed structure could cause double free of the
same memory region.
2. some methods does freeing of AM_MEDIA_TYPE without freeing
additional data (memory leak)
3. malloc return does not beeing checked for NULL value (out of memory).
Patch fixes all 3 issues.

-- 
Regards,
Vladimir Voroshilov     mailto:voroshil at gmail.com
JID: voroshil at jabber.ru
ICQ: 95587719
-------------- next part --------------
Index: outputpin.c
===================================================================
--- outputpin.c	(revision 22190)
+++ outputpin.c	(working copy)
@@ -79,6 +79,10 @@
     if (ppMediaTypes[0]->pbFormat)
     {
 	ppMediaTypes[0]->pbFormat=malloc(ppMediaTypes[0]->cbFormat);
+        if(!ppMediaTypes[0]->pbFormat){
+            ppMediaTypes[0]->cbFormat=0;
+            return E_OUTOFMEMORY;
+        }
 	memcpy(ppMediaTypes[0]->pbFormat, type->pbFormat, ppMediaTypes[0]->cbFormat);
     }
     if (cMediaTypes == 1)
@@ -147,6 +151,7 @@
  */
 static void CEnumMediaTypes_Destroy(CEnumMediaTypes* This)
 {
+    if(This->type.pbFormat) free(This->type.pbFormat);
     free(This->vt);
     free(This);
 }
@@ -178,6 +183,15 @@
 
     This->refcount = 1;
     This->type = *amt;
+    if (amt->cbFormat>0)
+    {
+	This->type.pbFormat=malloc(amt->cbFormat);
+        if(!This->type.pbFormat){
+            free(This);
+            return NULL;
+        }
+	memcpy(This->type.pbFormat, amt->pbFormat, amt->cbFormat);
+    }
 
     This->vt->QueryInterface = CEnumMediaTypes_QueryInterface;
     This->vt->AddRef = CEnumMediaTypes_AddRef;
@@ -372,6 +386,10 @@
     if (pmt->cbFormat>0)
     {
 	pmt->pbFormat=malloc(pmt->cbFormat);
+	if(!pmt->pbFormat){
+            pmt->cbFormat=0;
+            return E_OUTOFMEMORY;
+        }
 	memcpy(pmt->pbFormat, ((COutputPin*)This)->type.pbFormat, pmt->cbFormat);
     }
     return 0;
@@ -845,7 +863,16 @@
  */
 static void COutputPin_SetNewFormat(COutputPin* This, const AM_MEDIA_TYPE* amt)
 {
+    if(This->type.pbFormat) free(This->type.pbFormat);
     This->type = *amt;
+    if(amt->pbFormat){
+        This->type.pbFormat=malloc(amt->cbFormat);
+        if(!This->type.pbFormat) {
+            This->type.cbFormat=0;
+            return;
+        }
+        memcpy(This->type.pbFormat,amt->pbFormat,amt->cbFormat);
+    }
 }
 
 /**
@@ -856,6 +883,7 @@
  */
 static void COutputPin_Destroy(COutputPin* This)
 {
+    if(This->type.pbFormat) free(This->type.pbFormat);
     if (This->mempin->vt)
 	free(This->mempin->vt);
     if (This->mempin)
@@ -977,6 +1005,15 @@
     This->refcount = 1;
     This->remote = 0;
     This->type = *amt;
+    if(amt->cbFormat>0){
+        This->type.pbFormat=malloc(amt->cbFormat);
+        if(!This->type.pbFormat){
+            This->type.cbFormat=0;
+            COutputPin_Destroy(This);
+            return NULL;
+        }
+        memcpy(This->type.pbFormat,amt->pbFormat,amt->cbFormat);
+    }
 
     This->vt->QueryInterface = COutputPin_QueryInterface;
     This->vt->AddRef = COutputPin_AddRef;


More information about the MPlayer-dev-eng mailing list