While testing an application, I ran a into strange behaviour. Some of the tests use impersonation to run code as a different user, but they would always hang, never complete.
After some investigation, the problem was narrowed down to the use of mutexes. Originally, we used our own impersonation code based on the MSDN documentation, but even when using 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");
This never finishes, it's stuck on the line with the mutex creation. The documentation states that it should either throw an exception or return something, but does not mention blocking.
Some other observations, which might or might not be related:
- if we "impersonate" the current user, it returns immediately
- if we run the actual application and start another instance as a different user, everything works as intended
Probably there's something going on with underlying system resources, but we couldn't figure it out. How to make this work?
UPDATE: As per Hans' comment, I tried disabling Windows Defender, it didn't help. Here's a stacktrace of the place where it's hanging:
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