Race fix in dlls/winmm/mmsystem.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Maintainers,
I fixed a race condition in mmsystem.c that could cause heap corruption
(and has done so): The problem is that the proc_PlaySound thread could
exit (in case of error, like sound card not available) before the
assignment wps->hThread = CreateThread(...) was completed. At the end
of proc_PlaySound wps got freed, and the memory of wps->hThread gets
the next free pointer in the heap control area.

Please review my patch carefully. I am not that much experienced with
Windows and synchronisation, but I think, it should work.

Michael Karcher

Index: mmsystem.c
===================================================================
RCS file: /home/wine/wine/dlls/winmm/mmsystem.c,v
retrieving revision 1.54
diff -u -r1.54 mmsystem.c
--- mmsystem.c	22 May 2002 01:52:31 -0000	1.54
+++ mmsystem.c	26 May 2002 21:27:24 -0000
@@ -614,9 +614,29 @@
 
     if (fdwSound & SND_ASYNC) 
     {
-	wps->bLoop = fdwSound & SND_LOOP;
-        /* FIXME: memory leak in case of error & cs is still locked */
-        return ((wps->hThread = CreateThread(NULL, 0, proc_PlaySound, wps, 0, &id)) != 0);
+        HANDLE hAsyncThread;
+        HANDLE hReadyEvent;
+        DuplicateHandle(GetCurrentProcess(),wps->hReadyEvent,
+                        GetCurrentProcess(),&hReadyEvent,
+                        0, FALSE, DUPLICATE_SAME_ACCESS);
+        wps->bLoop = fdwSound & SND_LOOP;
+        /* FIXME: In case of error: cs is still locked? */
+        hAsyncThread = CreateThread(NULL, 0, proc_PlaySound, wps, 0, &id);
+        if(hAsyncThread != 0)
+        {
+            if(WaitForSingleObject(hReadyEvent,0) == WAIT_TIMEOUT)
+                wps->hThread = hAsyncThread;
+            CloseHandle(hReadyEvent);
+            return TRUE;
+        }
+        else
+        {
+            CloseHandle(hReadyEvent);
+            CloseHandle(wps->hReadyEvent);
+            if(wps->bAlloc) HeapFree(GetProcessHeap(),0,(void*)wps->pszSound);
+            HeapFree(GetProcessHeap(),0,wps);
+            return FALSE;
+        }
     }
 
     bRet = proc_PlaySound(wps);

-- 
use strict;sub rc4{my @k=unpack("C*",shift);my ($d,@s,$i,$s,@D,$x,$y,$X,
$Y)=(shift,0..255);$s=$s+$k[$i++%($#k+1)]+$_&255,($_,$s[$s])=($s[$s],$_)
for(@s);for(@D=unpack("C*",$d)){$X=$s[$x=$x+1&255];$Y=$s[$y=$X+$y&255];(
$s[$y],$s[$x])=($X,$Y);$_^=$s[$X+$Y&255];}pack("C*",@D);}1;#Don't export


[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux