Bug 1373147 - Log and refuse to load GMP DLLs which contain Win32 manifests. ?bobowen
The Windows sandbox blocks loading of GMP/CDM DLLs which contain Win32
manifests under certain conditions. So to make detecting this problem easier to
detect before we push out GMP/CDM updates, check when loading plugins whether
they have manifests, and log and refuse to load them if so.
This means we will detect GMP/CDM updates which regress (i.e. include a manifest)
during testing the new GMP/CDM update before pushing them out.
MozReview-Commit-ID: bfDY0MQ8lO
--- a/dom/media/gmp/GMPChild.cpp
+++ b/dom/media/gmp/GMPChild.cpp
@@ -319,26 +319,75 @@ GMPChild::GetUTF8LibPath(nsACString& aOu
nsAutoString path;
libFile->GetPath(path);
aOutLibPath = NS_ConvertUTF16toUTF8(path);
return true;
#endif
}
+#if defined(XP_WIN) && defined(MOZ_SANDBOX)
+BOOL CALLBACK
+EnumResourceTypesCallback(HMODULE aModule, LPTSTR aResType, LONG_PTR aOutParam)
+{
+ MOZ_ASSERT(aOutParam);
+ bool* hasManifest = reinterpret_cast<bool*>(aOutParam);
+ if (aResType == RT_MANIFEST) {
+ *hasManifest = true;
+ return FALSE; // Stop iteration.
+ }
+ // Continue iterating.
+ return TRUE;
+}
+
+static bool
+HasWin32Manifest(nsString aDLLPath)
+{
+ // Iterate through all resources in the DLL, and see if there's a manifest.
+ HMODULE module =
+ ::LoadLibraryExW(aDLLPath.get(),
+ NULL,
+ LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
+ MOZ_ASSERT(module);
+ if (module == NULL) {
+ return false;
+ }
+
+ bool hasManifest = false;
+ EnumResourceTypes(module,
+ &EnumResourceTypesCallback,
+ reinterpret_cast<LONG_PTR>(&hasManifest));
+
+ ::FreeLibrary(module);
+ return hasManifest;
+}
+#endif
+
mozilla::ipc::IPCResult
GMPChild::AnswerStartPlugin(const nsString& aAdapter)
{
LOGD("%s", __FUNCTION__);
nsCString libPath;
if (!GetUTF8LibPath(libPath)) {
return IPC_FAIL_NO_REASON(this);
}
+#if defined(XP_WIN) && defined(MOZ_SANDBOX)
+ {
+ // The Windows sandbox blocks loading of the plugin DLL if it contains
+ // a manifest under some conditions. So explicitly check for this and
+ // fail, so that it's detectable up front when testing new plugin updates.
+ if (HasWin32Manifest(NS_ConvertUTF8toUTF16(libPath))) {
+ LOGD("Can't load %s as it hass a Win32 Manifest.", libPath.get());
+ return IPC_FAIL_NO_REASON(this);
+ }
+ }
+#endif
+
auto platformAPI = new GMPPlatformAPI();
InitPlatformAPI(*platformAPI, this);
mGMPLoader = MakeUnique<GMPLoader>();
#if defined(MOZ_GMP_SANDBOX)
if (!mGMPLoader->CanSandbox()) {
LOGD("%s Can't sandbox GMP, failing", __FUNCTION__);
delete platformAPI;