Commit 14469472 authored by David Major's avatar David Major
Browse files

Bug 1355559: Suppress stack walking in LdrResolveDelayLoadedAPI. r=mstange,aklotz

parent dc3d8465
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -296,6 +296,24 @@ patched_LdrUnloadDll(HMODULE module)
  AutoSuppressStackWalking suppress;
  return stub_LdrUnloadDll(module);
}

// These pointers are disguised as PVOID to avoid pulling in obscure headers
typedef PVOID (WINAPI *LdrResolveDelayLoadedAPI_func)(PVOID ParentModuleBase,
  PVOID DelayloadDescriptor, PVOID FailureDllHook, PVOID FailureSystemHook,
  PVOID ThunkAddress, ULONG Flags);
static LdrResolveDelayLoadedAPI_func stub_LdrResolveDelayLoadedAPI;

static PVOID WINAPI patched_LdrResolveDelayLoadedAPI(PVOID ParentModuleBase,
  PVOID DelayloadDescriptor, PVOID FailureDllHook, PVOID FailureSystemHook,
  PVOID ThunkAddress, ULONG Flags)
{
  // Prevent the stack walker from suspending this thread when
  // LdrResolveDelayLoadAPI holds the RtlLookupFunctionEntry lock.
  AutoSuppressStackWalking suppress;
  return stub_LdrResolveDelayLoadedAPI(ParentModuleBase, DelayloadDescriptor,
                                       FailureDllHook, FailureSystemHook,
                                       ThunkAddress, Flags);
}
#endif // STACKWALK_HAS_DLL_INTERCEPTOR
#endif // _M_AMD64

@@ -388,6 +406,9 @@ EnsureWalkThreadReady()
  NtDllInterceptor.AddHook("LdrUnloadDll",
                           reinterpret_cast<intptr_t>(patched_LdrUnloadDll),
                           (void**)&stub_LdrUnloadDll);
  NtDllInterceptor.AddHook("LdrResolveDelayLoadedAPI",
                           reinterpret_cast<intptr_t>(patched_LdrResolveDelayLoadedAPI),
                           (void**)&stub_LdrResolveDelayLoadedAPI);
#endif

  InitializeDbgHelpCriticalSection();
+13 −0
Original line number Diff line number Diff line
@@ -243,6 +243,18 @@ bool TestLdrUnloadDll(void* aFunc)
  return patchedLdrUnloadDll(0) != 0;
}

bool TestLdrResolveDelayLoadedAPI(void* aFunc)
{
  // These pointers are disguised as PVOID to avoid pulling in obscure headers
  typedef PVOID (WINAPI *LdrResolveDelayLoadedAPIType)(PVOID, PVOID, PVOID,
                                                       PVOID, PVOID, ULONG);
  auto patchedLdrResolveDelayLoadedAPI =
    reinterpret_cast<LdrResolveDelayLoadedAPIType>(aFunc);
  // No idea how to call this API. Flags==99 is just an arbitrary number that
  // doesn't crash when the other params are null.
  return patchedLdrResolveDelayLoadedAPI(0, 0, 0, 0, 0, 99) == 0;
}

bool TestSetUnhandledExceptionFilter(void* aFunc)
{
  auto patchedSetUnhandledExceptionFilter =
@@ -471,6 +483,7 @@ int main()
#ifdef _M_X64
      TestHook(TestGetKeyState, "user32.dll", "GetKeyState") &&    // see Bug 1316415
      TestHook(TestLdrUnloadDll, "ntdll.dll", "LdrUnloadDll") &&
      TestHook(TestLdrResolveDelayLoadedAPI, "ntdll.dll", "LdrResolveDelayLoadedAPI") &&
#endif
      MaybeTestHook(ShouldTestTipTsf(), TestProcessCaretEvents, "tiptsf.dll", "ProcessCaretEvents") &&
#ifdef _M_IX86