summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscottmg <scottmg@chromium.org>2015-01-15 13:00:46 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-15 21:01:52 +0000
commit55a856eb124f941c191c62dab40055b827186395 (patch)
treed49845c9bf3b24015f9cf0b0f2f0913bfca49c13
parent4e37c9fa01a1683bd1e3460864e6813c8ea0313b (diff)
downloadchromium_src-55a856eb124f941c191c62dab40055b827186395.zip
chromium_src-55a856eb124f941c191c62dab40055b827186395.tar.gz
chromium_src-55a856eb124f941c191c62dab40055b827186395.tar.bz2
Fix font loading in OOP PDF
This does two things - avoids pdf.dll being loaded into the renderer when OOP PDF is being used (this was caused by the patching) - does the patch in PpapiThread when pdf.dll is loaded there for OOP The IAT patch to GetFontData allows various users of GDI font methods to succeed when sandboxed. R=cpu@chromium.org,raymes@chromium.org,ananta@chromium.org BUG=448473 Review URL: https://codereview.chromium.org/854773002 Cr-Commit-Position: refs/heads/master@{#311730}
-rw-r--r--chrome/renderer/chrome_render_process_observer.cc20
-rw-r--r--content/ppapi_plugin/ppapi_thread.cc58
2 files changed, 70 insertions, 8 deletions
diff --git a/chrome/renderer/chrome_render_process_observer.cc b/chrome/renderer/chrome_render_process_observer.cc
index 860dd32..9367b98 100644
--- a/chrome/renderer/chrome_render_process_observer.cc
+++ b/chrome/renderer/chrome_render_process_observer.cc
@@ -281,14 +281,18 @@ ChromeRenderProcessObserver::ChromeRenderProcessObserver(
net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider);
#if defined(OS_WIN)
- // Need to patch a few functions for font loading to work correctly.
- base::FilePath pdf;
- if (PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf) &&
- base::PathExists(pdf)) {
- g_iat_patch_createdca.Patch(
- pdf.value().c_str(), "gdi32.dll", "CreateDCA", CreateDCAPatch);
- g_iat_patch_get_font_data.Patch(
- pdf.value().c_str(), "gdi32.dll", "GetFontData", GetFontDataPatch);
+ // TODO(scottmg): http://crbug.com/448473. This code should be removed once
+ // PDF is always OOP and/or PDF is made to use Skia instead of GDI directly.
+ if (!command_line.HasSwitch(switches::kEnableOutOfProcessPdf)) {
+ // Need to patch a few functions for font loading to work correctly.
+ base::FilePath pdf;
+ if (PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf) &&
+ base::PathExists(pdf)) {
+ g_iat_patch_createdca.Patch(pdf.value().c_str(), "gdi32.dll", "CreateDCA",
+ CreateDCAPatch);
+ g_iat_patch_get_font_data.Patch(pdf.value().c_str(), "gdi32.dll",
+ "GetFontData", GetFontDataPatch);
+ }
}
#endif
diff --git a/content/ppapi_plugin/ppapi_thread.cc b/content/ppapi_plugin/ppapi_thread.cc
index 59edaaf..6d77afe 100644
--- a/content/ppapi_plugin/ppapi_thread.cc
+++ b/content/ppapi_plugin/ppapi_thread.cc
@@ -42,10 +42,12 @@
#include "ppapi/proxy/plugin_message_filter.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/resource_reply_thread_registrar.h"
+#include "ppapi/shared_impl/proxy_lock.h"
#include "third_party/WebKit/public/web/WebKit.h"
#include "ui/base/ui_base_switches.h"
#if defined(OS_WIN)
+#include "base/win/iat_patch_function.h"
#include "base/win/win_util.h"
#include "base/win/windows_version.h"
#include "sandbox/win/src/sandbox.h"
@@ -91,6 +93,53 @@ static void WarmupWindowsLocales(const ppapi::PpapiPermissions& permissions) {
}
}
}
+
+// TODO(scottmg): http://crbug.com/448473. This code should be removed from the
+// renderer once PDF is always OOP and/or PDF is made to use Skia instead of GDI
+// directly.
+const wchar_t kPdfFileName[] = L"pdf.dll";
+
+static base::win::IATPatchFunction g_iat_patch_createdca;
+HDC WINAPI CreateDCAPatch(LPCSTR driver_name,
+ LPCSTR device_name,
+ LPCSTR output,
+ const void* init_data) {
+ DCHECK(std::string("DISPLAY") == std::string(driver_name));
+ DCHECK(!device_name);
+ DCHECK(!output);
+ DCHECK(!init_data);
+
+ // CreateDC fails behind the sandbox, but not CreateCompatibleDC.
+ return CreateCompatibleDC(NULL);
+}
+
+static base::win::IATPatchFunction g_iat_patch_get_font_data;
+DWORD WINAPI GetFontDataPatch(HDC hdc,
+ DWORD table,
+ DWORD offset,
+ LPVOID buffer,
+ DWORD length) {
+ int rv = GetFontData(hdc, table, offset, buffer, length);
+ if (rv == GDI_ERROR && hdc) {
+ HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT));
+
+ LOGFONT logfont;
+ if (GetObject(font, sizeof(LOGFONT), &logfont)) {
+ std::vector<char> font_data;
+ {
+ ppapi::ProxyAutoLock lock;
+ // In the sandbox, font loading will fail. We ask the browser to load it
+ // which causes it to be loaded by the kernel, which then makes the
+ // subsequent call succeed.
+ ppapi::proxy::PluginGlobals::Get()->PreCacheFontForFlash(
+ reinterpret_cast<const void*>(&logfont));
+ }
+ rv = GetFontData(hdc, table, offset, buffer, length);
+ }
+ }
+ return rv;
+}
+
#else
extern void* g_target_services;
#endif
@@ -325,6 +374,15 @@ void PpapiThread::OnLoadPlugin(const base::FilePath& path,
// otherwise these would be silent terminations and fly under the radar).
base::win::SetAbortBehaviorForCrashReporting();
+ // Need to patch a few functions for font loading to work correctly. This can
+ // be removed once we switch PDF to use Skia.
+ if (GetModuleHandle(kPdfFileName)) {
+ g_iat_patch_createdca.Patch(kPdfFileName, "gdi32.dll", "CreateDCA",
+ CreateDCAPatch);
+ g_iat_patch_get_font_data.Patch(kPdfFileName, "gdi32.dll", "GetFontData",
+ GetFontDataPatch);
+ }
+
// Once we lower the token the sandbox is locked down and no new modules
// can be loaded. TODO(cpu): consider changing to the loading style of
// regular plugins.