OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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 "chrome/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 "chrome/common/chrome_constants.h" | |
11 #include "chrome/common/chrome_switches.h" | |
12 #include "content/common/injection_test_dll.h" | |
13 #include "sandbox/src/sandbox.h" | |
14 #include "unicode/timezone.h" | |
15 | |
16 namespace { | |
17 | |
18 // In order to have Theme support, we need to connect to the theme service. | |
19 // This needs to be done before we lock down the renderer. Officially this | |
20 // can be done with OpenThemeData() but it fails unless you pass a valid | |
21 // window at least the first time. Interestingly, the very act of creating a | |
22 // window also sets the connection to the theme service. | |
23 void EnableThemeSupportForRenderer(bool no_sandbox) { | |
24 HWINSTA current = NULL; | |
25 HWINSTA winsta0 = NULL; | |
26 | |
27 if (!no_sandbox) { | |
28 current = ::GetProcessWindowStation(); | |
29 winsta0 = ::OpenWindowStationW(L"WinSta0", FALSE, GENERIC_READ); | |
30 if (!winsta0 || !::SetProcessWindowStation(winsta0)) { | |
31 // Could not set the alternate window station. There is a possibility | |
32 // that the theme wont be correctly initialized on XP. | |
33 NOTREACHED() << "Unable to switch to WinSt0"; | |
34 } | |
35 } | |
36 | |
37 HWND window = ::CreateWindowExW(0, L"Static", L"", WS_POPUP | WS_DISABLED, | |
38 CW_USEDEFAULT, 0, 0, 0, HWND_MESSAGE, NULL, | |
39 ::GetModuleHandleA(NULL), NULL); | |
40 if (!window) { | |
41 DLOG(WARNING) << "failed to enable theme support"; | |
42 } else { | |
43 ::DestroyWindow(window); | |
44 } | |
45 | |
46 if (!no_sandbox) { | |
47 // Revert the window station. | |
48 if (!current || !::SetProcessWindowStation(current)) { | |
49 // We failed to switch back to the secure window station. This might | |
50 // confuse the renderer enough that we should kill it now. | |
51 LOG(FATAL) << "Failed to restore alternate window station"; | |
52 } | |
53 | |
54 if (!::CloseWindowStation(winsta0)) { | |
55 // We might be leaking a winsta0 handle. This is a security risk, but | |
56 // since we allow fail over to no desktop protection in low memory | |
57 // condition, this is not a big risk. | |
58 NOTREACHED(); | |
59 } | |
60 } | |
61 } | |
62 | |
63 } // namespace | |
64 | |
65 RendererMainPlatformDelegate::RendererMainPlatformDelegate( | |
66 const MainFunctionParams& parameters) | |
67 : parameters_(parameters), | |
68 sandbox_test_module_(NULL) { | |
69 } | |
70 | |
71 RendererMainPlatformDelegate::~RendererMainPlatformDelegate() { | |
72 } | |
73 | |
74 void RendererMainPlatformDelegate::PlatformInitialize() { | |
75 // Be mindful of what resources you acquire here. They can be used by | |
76 // malicious code if the renderer gets compromised. | |
77 const CommandLine& command_line = parameters_.command_line_; | |
78 bool no_sandbox = command_line.HasSwitch(switches::kNoSandbox); | |
79 EnableThemeSupportForRenderer(no_sandbox); | |
80 | |
81 if (!no_sandbox) { | |
82 // ICU DateFormat class (used in base/time_format.cc) needs to get the | |
83 // Olson timezone ID by accessing the registry keys under | |
84 // HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones. | |
85 // After TimeZone::createDefault is called once here, the timezone ID is | |
86 // cached and there's no more need to access the registry. If the sandbox | |
87 // is disabled, we don't have to make this dummy call. | |
88 scoped_ptr<icu::TimeZone> zone(icu::TimeZone::createDefault()); | |
89 } | |
90 } | |
91 | |
92 void RendererMainPlatformDelegate::PlatformUninitialize() { | |
93 } | |
94 | |
95 bool RendererMainPlatformDelegate::InitSandboxTests(bool no_sandbox) { | |
96 const CommandLine& command_line = parameters_.command_line_; | |
97 | |
98 DVLOG(1) << "Started renderer with " << command_line.command_line_string(); | |
99 | |
100 sandbox::TargetServices* target_services = | |
101 parameters_.sandbox_info_.TargetServices(); | |
102 | |
103 if (target_services && !no_sandbox) { | |
104 std::wstring test_dll_name = | |
105 command_line.GetSwitchValueNative(switches::kTestSandbox); | |
106 if (!test_dll_name.empty()) { | |
107 sandbox_test_module_ = LoadLibrary(test_dll_name.c_str()); | |
108 DCHECK(sandbox_test_module_); | |
109 if (!sandbox_test_module_) { | |
110 return false; | |
111 } | |
112 } | |
113 } | |
114 return true; | |
115 } | |
116 | |
117 bool RendererMainPlatformDelegate::EnableSandbox() { | |
118 sandbox::TargetServices* target_services = | |
119 parameters_.sandbox_info_.TargetServices(); | |
120 | |
121 if (target_services) { | |
122 target_services->LowerToken(); | |
123 return true; | |
124 } | |
125 return false; | |
126 } | |
127 | |
128 void RendererMainPlatformDelegate::RunSandboxTests() { | |
129 if (sandbox_test_module_) { | |
130 RunRendererTests run_security_tests = | |
131 reinterpret_cast<RunRendererTests>(GetProcAddress(sandbox_test_module_, | |
132 kRenderTestCall)); | |
133 DCHECK(run_security_tests); | |
134 if (run_security_tests) { | |
135 int test_count = 0; | |
136 DVLOG(1) << "Running renderer security tests"; | |
137 BOOL result = run_security_tests(&test_count); | |
138 CHECK(result) << "Test number " << test_count << " has failed."; | |
139 } | |
140 } | |
141 } | |
OLD | NEW |