Mutex creation freezes when using impersonation

While testing the application, I came across strange behavior. Some of the tests use impersonation to run the code as another user, but they always hang, never complete.

After some research, the problem was narrowed down to using mutexes. We initially used our own impersonation code based on the MSDN documentation , but even with the SimpleImpersonation library, the problem still remains. Here is a minimal example to reproduce the problem:

using (Impersonation.LogonUser(DOMAIN, USER, PASSWORD, LogonType.Interactive)) { Console.WriteLine("Impersonated"); bool mine; using (new Mutex(true, "Mutex", out mine)) { if (!mine) throw new Exception("Couldn't get mutex"); Console.WriteLine("Got mutex"); } } Console.WriteLine("Finished"); 

It never ends; it is stuck on the line with the creation of a mutex. The documentation states that it should either throw an exception or return something, but does not mention a lock.

Some other observations that may or may not be related:

  • if we “impersonate” the current user, he immediately returns
  • if we run the actual application and run another instance as a different user, everything works as intended

Something may be happening with the underlying system resources, but we could not figure it out. How to do it?

UPDATE: According to Hans comment, I tried disabling Windows Defender, this did not help. Here is the stop path of the place where it hangs:

 ntdll.dll!_NtWaitForSingleObject@12 () KernelBase.dll!_WaitForSingleObjectEx@12 () mscorlib.ni.dll!719c1867() [Frames below may be incorrect and/or missing, native debugger attempting to walk managed call stack] mscorlib.ni.dll!719c1852() [Managed to Native Transition] mscorlib.dll!System.Threading.Mutex.CreateMutexHandle(bool initiallyOwned, string name, Microsoft.Win32.Win32Native.SECURITY_ATTRIBUTES securityAttribute, out Microsoft.Win32.SafeHandles.SafeWaitHandle mutexHandle) mscorlib.dll!System.Threading.Mutex.MutexTryCodeHelper.MutexTryCode(object userData) [Native to Managed Transition] [Managed to Native Transition] mscorlib.dll!System.Threading.Mutex.CreateMutexWithGuaranteedCleanup(bool initiallyOwned, string name, out bool createdNew, Microsoft.Win32.Win32Native.SECURITY_ATTRIBUTES secAttrs) mscorlib.dll!System.Threading.Mutex.Mutex(bool initiallyOwned, string name, out bool createdNew, System.Security.AccessControl.MutexSecurity mutexSecurity) mscorlib.dll!System.Threading.Mutex.Mutex(bool initiallyOwned, string name, out bool createdNew) MutexImpersonationTest.exe!MutexImpersonationTest.Program.Main(string[] args) Line 16 
+5
source share
1 answer

It seems that the code to get Mutex is stuck in an infinite loop, and in my tests it binds one core with 100% to the new Mutex(...) call.

The reason for this is that the structure code first tries to call Win32 CreateMutex , if this fails with the "Access Denied" error, it calls the OpenMutex call OpenMutex . If the OpenMutex call fails with an error indicating that the mutex does not exist, it repeats the whole process again and therefore gets stuck in an infinite loop if the mutex does not exist.

According to the CreateMutex documentation , this is essentially the right approach, but does not seem to take into account the case where the initial CreateMutex does not work with Access Denied, which is not related to the rights to an existing mutex.

One thing that seemed to work when I tried it was a mutex name prefix with the name Global, hope this is the right solution for you.

+7
source

Source: https://habr.com/ru/post/1247015/


All Articles