[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