Bug 1108035 - Add a preference that allows us to disable Flash protected mode from within Firefox. We do this by hooking CreateFileW and replacing the Flash config file with our own. r=aklotz

This commit is contained in:
Benjamin Smedberg
2014-12-12 10:19:06 -05:00
parent a8acbbe22a
commit c5bf7a3d77
7 changed files with 138 additions and 3 deletions

View File

@@ -409,7 +409,7 @@ GetNewPluginLibrary(nsPluginTag *aPluginTag)
} }
if (nsNPAPIPlugin::RunPluginOOP(aPluginTag)) { if (nsNPAPIPlugin::RunPluginOOP(aPluginTag)) {
return PluginModuleChromeParent::LoadModule(aPluginTag->mFullPath.get(), aPluginTag->mId); return PluginModuleChromeParent::LoadModule(aPluginTag->mFullPath.get(), aPluginTag->mId, aPluginTag);
} }
return new PluginPRLibrary(aPluginTag->mFullPath.get(), aPluginTag->mLibrary); return new PluginPRLibrary(aPluginTag->mFullPath.get(), aPluginTag->mLibrary);
} }

View File

@@ -45,6 +45,8 @@ both:
async ProcessNativeEventsInInterruptCall(); async ProcessNativeEventsInInterruptCall();
child: child:
async DisableFlashProtectedMode();
// Forces the child process to update its plugin function table. // Forces the child process to update its plugin function table.
intr NP_GetEntryPoints() intr NP_GetEntryPoints()
returns (NPError rv); returns (NPError rv);

View File

@@ -76,6 +76,16 @@ static PRLibrary *sGtkLib = nullptr;
#endif #endif
#ifdef XP_WIN #ifdef XP_WIN
// Hooking CreateFileW for protected-mode magic
static WindowsDllInterceptor sKernel32Intercept;
typedef HANDLE (WINAPI *CreateFileWPtr)(LPCWSTR fname, DWORD access,
DWORD share,
LPSECURITY_ATTRIBUTES security,
DWORD creation, DWORD flags,
HANDLE ftemplate);
static CreateFileWPtr sCreateFileWStub = nullptr;
static WCHAR* sReplacementConfigFile;
// Used with fix for flash fullscreen window loosing focus. // Used with fix for flash fullscreen window loosing focus.
static bool gDelayFlashFocusReplyUntilEval = false; static bool gDelayFlashFocusReplyUntilEval = false;
// Used to fix GetWindowInfo problems with internal flash settings dialogs // Used to fix GetWindowInfo problems with internal flash settings dialogs
@@ -219,6 +229,18 @@ PluginModuleChild::InitForContent(base::ProcessHandle aParentProcessHandle,
return true; return true;
} }
bool
PluginModuleChild::RecvDisableFlashProtectedMode()
{
MOZ_ASSERT(mIsChrome);
#ifdef XP_WIN
HookProtectedMode();
#else
MOZ_ASSERT(false, "Should not be called");
#endif
return true;
}
bool bool
PluginModuleChild::InitForChrome(const std::string& aPluginFilename, PluginModuleChild::InitForChrome(const std::string& aPluginFilename,
base::ProcessHandle aParentProcessHandle, base::ProcessHandle aParentProcessHandle,
@@ -1887,9 +1909,99 @@ PluginModuleChild::AnswerNP_Initialize(const PluginSettings& aSettings, NPError*
#else #else
# error Please implement me for your platform # error Please implement me for your platform
#endif #endif
#ifdef XP_WIN
CleanupProtectedModeHook();
#endif
} }
#if defined(XP_WIN) #if defined(XP_WIN)
HANDLE WINAPI
CreateFileHookFn(LPCWSTR fname, DWORD access, DWORD share,
LPSECURITY_ATTRIBUTES security, DWORD creation, DWORD flags,
HANDLE ftemplate)
{
static const WCHAR kConfigFile[] = L"mms.cfg";
static const size_t kConfigLength = ArrayLength(kConfigFile) - 1;
while (true) { // goto out, in sheep's clothing
size_t len = wcslen(fname);
if (len < kConfigLength) {
break;
}
if (wcscmp(fname + len - kConfigLength, kConfigFile) != 0) {
break;
}
// This is the config file we want to rewrite
WCHAR tempPath[MAX_PATH+1];
if (GetTempPathW(MAX_PATH, tempPath) == 0) {
break;
}
WCHAR tempFile[MAX_PATH+1];
if (GetTempFileNameW(tempPath, L"fx", 0, tempFile) == 0) {
break;
}
HANDLE replacement =
sCreateFileWStub(tempFile, GENERIC_READ | GENERIC_WRITE, share,
security, TRUNCATE_EXISTING,
FILE_ATTRIBUTE_TEMPORARY,
NULL);
if (replacement == INVALID_HANDLE_VALUE) {
break;
}
HANDLE original = sCreateFileWStub(fname, access, share, security,
creation, flags, ftemplate);
if (original != INVALID_HANDLE_VALUE) {
// copy original to replacement
static const size_t kBufferSize = 1024;
char buffer[kBufferSize];
DWORD bytes;
while (ReadFile(original, buffer, kBufferSize, &bytes, NULL)) {
if (bytes == 0) {
break;
}
DWORD wbytes;
WriteFile(replacement, buffer, bytes, &wbytes, NULL);
if (bytes < kBufferSize) {
break;
}
}
CloseHandle(original);
}
static const char kSettingString[] = "\nProtectedMode=0\n";
DWORD wbytes;
WriteFile(replacement, static_cast<const void*>(kSettingString),
sizeof(kSettingString) - 1, &wbytes, NULL);
SetFilePointer(replacement, 0, NULL, FILE_BEGIN);
sReplacementConfigFile = _wcsdup(tempFile);
return replacement;
}
return sCreateFileWStub(fname, access, share, security, creation, flags,
ftemplate);
}
void
PluginModuleChild::HookProtectedMode()
{
sKernel32Intercept.Init("kernel32.dll");
sKernel32Intercept.AddHook("CreateFileW",
reinterpret_cast<intptr_t>(CreateFileHookFn),
(void**) &sCreateFileWStub);
}
void
PluginModuleChild::CleanupProtectedModeHook()
{
if (sReplacementConfigFile) {
DeleteFile(sReplacementConfigFile);
free(sReplacementConfigFile);
sReplacementConfigFile = nullptr;
}
}
BOOL WINAPI BOOL WINAPI
PMCGetWindowInfoHook(HWND hWnd, PWINDOWINFO pwi) PMCGetWindowInfoHook(HWND hWnd, PWINDOWINFO pwi)
{ {

View File

@@ -75,6 +75,7 @@ protected:
virtual bool RecvSettingChanged(const PluginSettings& aSettings) MOZ_OVERRIDE; virtual bool RecvSettingChanged(const PluginSettings& aSettings) MOZ_OVERRIDE;
// Implement the PPluginModuleChild interface // Implement the PPluginModuleChild interface
virtual bool RecvDisableFlashProtectedMode() MOZ_OVERRIDE;
virtual bool AnswerNP_GetEntryPoints(NPError* rv) MOZ_OVERRIDE; virtual bool AnswerNP_GetEntryPoints(NPError* rv) MOZ_OVERRIDE;
virtual bool AnswerNP_Initialize(const PluginSettings& aSettings, NPError* rv) MOZ_OVERRIDE; virtual bool AnswerNP_Initialize(const PluginSettings& aSettings, NPError* rv) MOZ_OVERRIDE;
@@ -293,6 +294,12 @@ private:
void InitQuirksModes(const nsCString& aMimeType); void InitQuirksModes(const nsCString& aMimeType);
bool InitGraphics(); bool InitGraphics();
void DeinitGraphics(); void DeinitGraphics();
#if defined(OS_WIN)
void HookProtectedMode();
void CleanupProtectedModeHook();
#endif
#if defined(MOZ_WIDGET_GTK) #if defined(MOZ_WIDGET_GTK)
static gboolean DetectNestedEventLoop(gpointer data); static gboolean DetectNestedEventLoop(gpointer data);
static gboolean ProcessBrowserEvents(gpointer data); static gboolean ProcessBrowserEvents(gpointer data);

View File

@@ -31,6 +31,7 @@
#include "nsPrintfCString.h" #include "nsPrintfCString.h"
#include "prsystem.h" #include "prsystem.h"
#include "GeckoProfiler.h" #include "GeckoProfiler.h"
#include "nsPluginTags.h"
#ifdef XP_WIN #ifdef XP_WIN
#include "PluginHangUIParent.h" #include "PluginHangUIParent.h"
@@ -153,7 +154,8 @@ PluginModuleContentParent::Create(mozilla::ipc::Transport* aTransport,
// static // static
PluginLibrary* PluginLibrary*
PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId) PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId,
nsPluginTag* aPluginTag)
{ {
PLUGIN_LOG_DEBUG_FUNCTION; PLUGIN_LOG_DEBUG_FUNCTION;
@@ -192,6 +194,13 @@ PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId)
#endif #endif
#endif #endif
#ifdef XP_WIN
if (aPluginTag->mIsFlashPlugin &&
Preferences::GetBool("dom.ipc.plugins.flash.disable-protected-mode", false)) {
parent->SendDisableFlashProtectedMode();
}
#endif
return parent.forget(); return parent.forget();
} }

View File

@@ -28,6 +28,8 @@
#include "nsExceptionHandler.h" #include "nsExceptionHandler.h"
#endif #endif
class nsPluginTag;
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
class PCrashReporterParent; class PCrashReporterParent;
@@ -295,7 +297,8 @@ class PluginModuleChromeParent
* This may or may not launch a plugin child process, * This may or may not launch a plugin child process,
* and may or may not be very expensive. * and may or may not be very expensive.
*/ */
static PluginLibrary* LoadModule(const char* aFilePath, uint32_t aPluginId); static PluginLibrary* LoadModule(const char* aFilePath, uint32_t aPluginId,
nsPluginTag* aPluginTag);
virtual ~PluginModuleChromeParent(); virtual ~PluginModuleChromeParent();

View File

@@ -2354,6 +2354,8 @@ pref("dom.ipc.tabs.shutdownTimeoutSecs", 0);
pref("dom.ipc.plugins.java.enabled", false); pref("dom.ipc.plugins.java.enabled", false);
#endif #endif
pref("dom.ipc.plugins.flash.disable-protected-mode", false);
pref("dom.ipc.plugins.flash.subprocess.crashreporter.enabled", true); pref("dom.ipc.plugins.flash.subprocess.crashreporter.enabled", true);
pref("dom.ipc.plugins.reportCrashURL", true); pref("dom.ipc.plugins.reportCrashURL", true);