1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/renderer/renderer_main_platform_delegate.h" 6 7#include "base/command_line.h" 8#include "base/logging.h" 9#include "base/memory/scoped_ptr.h" 10#include "base/strings/string16.h" 11#include "base/win/win_util.h" 12#include "content/public/common/content_switches.h" 13#include "content/public/common/injection_test_win.h" 14#include "content/public/renderer/render_thread.h" 15#include "content/renderer/render_thread_impl.h" 16#include "sandbox/win/src/sandbox.h" 17#include "skia/ext/vector_platform_device_emf_win.h" 18#include "third_party/icu/source/i18n/unicode/timezone.h" 19#include "third_party/skia/include/ports/SkTypeface_win.h" 20 21#ifdef ENABLE_VTUNE_JIT_INTERFACE 22#include "v8/src/third_party/vtune/v8-vtune.h" 23#endif 24 25namespace content { 26namespace { 27 28// Windows-only skia sandbox support 29void SkiaPreCacheFont(const LOGFONT& logfont) { 30 RenderThread* render_thread = RenderThread::Get(); 31 if (render_thread) { 32 render_thread->PreCacheFont(logfont); 33 } 34} 35 36void SkiaPreCacheFontCharacters(const LOGFONT& logfont, 37 const wchar_t* text, 38 unsigned int text_length) { 39 RenderThreadImpl* render_thread_impl = RenderThreadImpl::current(); 40 if (render_thread_impl) { 41 render_thread_impl->PreCacheFontCharacters( 42 logfont, 43 base::string16(text, text_length)); 44 } 45} 46 47#if !defined(NDEBUG) 48LRESULT CALLBACK WindowsHookCBT(int code, WPARAM w_param, LPARAM l_param) { 49 CHECK_NE(code, HCBT_CREATEWND) 50 << "Should not be creating windows in the renderer!"; 51 return CallNextHookEx(NULL, code, w_param, l_param); 52} 53#endif // !NDEBUG 54 55} // namespace 56 57RendererMainPlatformDelegate::RendererMainPlatformDelegate( 58 const MainFunctionParams& parameters) 59 : parameters_(parameters), 60 sandbox_test_module_(NULL) { 61} 62 63RendererMainPlatformDelegate::~RendererMainPlatformDelegate() { 64} 65 66void RendererMainPlatformDelegate::PlatformInitialize() { 67#if !defined(NDEBUG) 68 // Install a check that we're not creating windows in the renderer. See 69 // http://crbug.com/230122 for background. TODO(scottmg): Ideally this would 70 // check all threads in the renderer, but it currently only checks the main 71 // thread. 72 PCHECK( 73 SetWindowsHookEx(WH_CBT, WindowsHookCBT, NULL, ::GetCurrentThreadId())); 74#endif // !NDEBUG 75 76 const CommandLine& command_line = parameters_.command_line; 77 78#ifdef ENABLE_VTUNE_JIT_INTERFACE 79 if (command_line.HasSwitch(switches::kEnableVtune)) 80 vTune::InitializeVtuneForV8(); 81#endif 82 83 // Be mindful of what resources you acquire here. They can be used by 84 // malicious code if the renderer gets compromised. 85 bool no_sandbox = command_line.HasSwitch(switches::kNoSandbox); 86 87 if (!no_sandbox) { 88 // ICU DateFormat class (used in base/time_format.cc) needs to get the 89 // Olson timezone ID by accessing the registry keys under 90 // HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones. 91 // After TimeZone::createDefault is called once here, the timezone ID is 92 // cached and there's no more need to access the registry. If the sandbox 93 // is disabled, we don't have to make this dummy call. 94 scoped_ptr<icu::TimeZone> zone(icu::TimeZone::createDefault()); 95 SkTypeface_SetEnsureLOGFONTAccessibleProc(SkiaPreCacheFont); 96 skia::SetSkiaEnsureTypefaceCharactersAccessible( 97 SkiaPreCacheFontCharacters); 98 } 99} 100 101void RendererMainPlatformDelegate::PlatformUninitialize() { 102} 103 104bool RendererMainPlatformDelegate::InitSandboxTests(bool no_sandbox) { 105 const CommandLine& command_line = parameters_.command_line; 106 107 DVLOG(1) << "Started renderer with " << command_line.GetCommandLineString(); 108 109 sandbox::TargetServices* target_services = 110 parameters_.sandbox_info->target_services; 111 112 if (target_services && !no_sandbox) { 113 std::wstring test_dll_name = 114 command_line.GetSwitchValueNative(switches::kTestSandbox); 115 if (!test_dll_name.empty()) { 116 sandbox_test_module_ = LoadLibrary(test_dll_name.c_str()); 117 DCHECK(sandbox_test_module_); 118 if (!sandbox_test_module_) { 119 return false; 120 } 121 } 122 } 123 return true; 124} 125 126bool RendererMainPlatformDelegate::EnableSandbox() { 127 sandbox::TargetServices* target_services = 128 parameters_.sandbox_info->target_services; 129 130 if (target_services) { 131 // Cause advapi32 to load before the sandbox is turned on. 132 unsigned int dummy_rand; 133 rand_s(&dummy_rand); 134 // Warm up language subsystems before the sandbox is turned on. 135 ::GetUserDefaultLangID(); 136 ::GetUserDefaultLCID(); 137 138 target_services->LowerToken(); 139 return true; 140 } 141 return false; 142} 143 144void RendererMainPlatformDelegate::RunSandboxTests(bool no_sandbox) { 145 if (sandbox_test_module_) { 146 RunRendererTests run_security_tests = 147 reinterpret_cast<RunRendererTests>(GetProcAddress(sandbox_test_module_, 148 kRenderTestCall)); 149 DCHECK(run_security_tests); 150 if (run_security_tests) { 151 int test_count = 0; 152 DVLOG(1) << "Running renderer security tests"; 153 BOOL result = run_security_tests(&test_count); 154 CHECK(result) << "Test number " << test_count << " has failed."; 155 } 156 } 157} 158 159} // namespace content 160