Bug 1720746 - Preload bcryptPrimitives.dll in the main thread of GMP. r=bobowen

The call to `RtlGenRandom` delay-loads bcryptPrimitives.dll.  The GMP process,
however, cannot load bcryptPrimitives.dll after process launch because its process
token is restricted.  This is not a problem normally because bcryptPrimitives.dll
is loaded in early stage when the main thread still has a non-restricted impersonation
token.

With ASan, however, the first call to `RandomUint64` happens in a non-main thread,
and it fails because the thread is not impersonated.  We have PreloadLibs to mitigate
this kind of problem, but in this case adding bcryptPrimitives.dll to the list does
not help because the call to `RandomUint64` happens before we load PreloadLibs.

The proposed fix is to explicitly call `RandomUint64` in the main thread before
any call to `RandomUint64` in the process.

Differential Revision: https://phabricator.services.mozilla.com/D121203
This commit is contained in:
Toshihito Kikuchi 2021-07-29 15:40:47 +00:00
Родитель 3dadc4fd12
Коммит 3abb5523e2
1 изменённых файлов: 13 добавлений и 0 удалений

Просмотреть файл

@ -21,6 +21,9 @@
# include <process.h>
# include <shobjidl.h>
# include "mozilla/ipc/WindowsMessageLoop.h"
# ifdef MOZ_ASAN
# include "mozilla/RandomNum.h"
# endif
# include "mozilla/ScopeExit.h"
# include "mozilla/WinDllServices.h"
#endif
@ -670,6 +673,16 @@ nsresult XRE_InitChildProcess(int aArgc, char* aArgv[],
break;
case GeckoProcessType_GMPlugin:
#if defined(XP_WIN) && defined(MOZ_ASAN)
// RandomUint64 delayloads bcryptPrimitives.dll. Without ASan,
// it's loaded in the main thread which has the non-restricted
// impersonation token. With ASan, on the other hand, the first
// call to RandomUint64 happens in a non-main thread before loading
// PreloadLibs, resulting in failure because the thread is not
// impersonated and the process token is restricted. RandomUint64
// below is a quick workaround to make delayload modules loaded.
RandomUint64OrDie();
#endif
process = MakeUnique<gmp::GMPProcessChild>(parentPID);
break;