Race fix in dlls/winmm/mmsystem.c
Michael Karcher
michael.karcher at dpk.berlin.fido.de
Sun May 26 16:45:22 CDT 2002
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, at s,$i,$s, at 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*", at D);}1;#Don't export
More information about the wine-patches
mailing list