[ros-dev] Kernel32 race condition

Joseph Galbraith galb at vandyke.com
Wed Nov 30 19:18:39 CET 2005


The DllMain() help in the PSDK has the following
tidbit:

> While it is acceptable to create synchronization objects in 
> DllMain, you should not perform synchronization in DllMain (or
>  a function called by DllMain) because all calls to DllMain
> are serialized. Waiting on synchronization objects in DllMain
> can cause a deadlock.

Does ReactOS serialize calls to DllMain?  I would think if it
was, CreateRemoteThread() would block waiting for
DLL_THREAD_ATTACH until DLL_PROCESS_DETACH had finished.

(And then of course, there are other issues to be dealt
with because the DLL is unloaded.)

ExitProcess() PSDK has the following tidbit which might
also help:

> The ExitProcess, ExitThread, CreateThread, CreateRemoteThread
> functions, and a process that is starting (as the result of a
> call by CreateProcess) are serialized between each other
> within a process. Only one of these events can happen in an
> address space at a time. This means the following restrictions
> hold:
> 
> During process startup and DLL initialization routines, new
> threads can be created, but they do not begin execution until
> DLL initialization is done for the process. Only one thread in
> a process can be in a DLL initialization or detach routine at
> a time. If any process is in its DLL initialization or detach
> routine, ExitProcess does not return.

Hope this helps.

Thanks,

Joseph

Ge van Geldorp wrote:
> While working on proper logoff/shutdown processing, I'm 
> running into an interesting race condition inside kernel32. 
> The shutdown command (apps/utils/shutdown) calls 
> ExitWindowsEx() and then terminates, which causes kernel32's 
> DllMain() function to be called with the DLL_PROCESS_DETACH 
> reason. This will clean up kernel32 resources, like calling 
> RtlDeleteCriticalSection(&ConsoleLock).
> 
> Now, before the process is completely shutdown, CSRSS will 
> send it a CTRL_LOGOFF_EVENT. To deliver this event, CSRSS 
> calls CreateRemoteThread(). So CreateRemoteThread() is called 
> while the main thread is executing DLL_PROCESS_DETACH cleanup.
>  During handling of CTRL_LOGOFF_EVENT, the new thread will try
>  to enter the ConsoleLock critical section, which was already
>  deleted by the main thread. Chaos results.
> 
> To solve this, first I was looking for a way to disable new 
> thread creation when a process enters ExitProcess(), but that 
> won't solve the problem. We can still have a thread A which 
> calls ExitProcess(), have a context switch to existing thread 
> B of the same process which does something that needs the 
> ConsoleLock. Then I considered SuspendThread()ing all other 
> threads of the process when ExitProcess() is called, but that 
> could potentially lead to deadlocks if the suspended threads 
> hold synchronization objects. So now I'm inclined to believe 
> that the solution is to just not do the resource cleanup 
> during DLL_PROCESS_DETACH handling. But that doesn't feel very
>  clean either. Anyone have a better idea?
> 
> GvG
> 
> _______________________________________________ Ros-dev 
> mailing list Ros-dev at reactos.org 
> http://www.reactos.org/mailman/listinfo/ros-dev
> 



More information about the Ros-dev mailing list