OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/gpu/gpu_process_host.h" | 5 #include "content/browser/gpu/gpu_process_host.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/base_switches.h" | 8 #include "base/base_switches.h" |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/debug/trace_event.h" | 12 #include "base/debug/trace_event.h" |
13 #include "base/logging.h" | |
13 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
14 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
15 #include "base/process_util.h" | 16 #include "base/process_util.h" |
16 #include "base/sha1.h" | 17 #include "base/sha1.h" |
17 #include "base/threading/thread.h" | 18 #include "base/threading/thread.h" |
18 #include "content/browser/browser_child_process_host_impl.h" | 19 #include "content/browser/browser_child_process_host_impl.h" |
19 #include "content/browser/gpu/gpu_data_manager_impl.h" | 20 #include "content/browser/gpu/gpu_data_manager_impl.h" |
20 #include "content/browser/gpu/gpu_process_host_ui_shim.h" | 21 #include "content/browser/gpu/gpu_process_host_ui_shim.h" |
21 #include "content/browser/gpu/gpu_surface_tracker.h" | 22 #include "content/browser/gpu/gpu_surface_tracker.h" |
22 #include "content/browser/gpu/shader_disk_cache.h" | 23 #include "content/browser/gpu/shader_disk_cache.h" |
(...skipping 16 matching lines...) Expand all Loading... | |
39 #include "gpu/command_buffer/service/gpu_switches.h" | 40 #include "gpu/command_buffer/service/gpu_switches.h" |
40 #include "ipc/ipc_channel_handle.h" | 41 #include "ipc/ipc_channel_handle.h" |
41 #include "ipc/ipc_switches.h" | 42 #include "ipc/ipc_switches.h" |
42 #include "ui/gl/gl_switches.h" | 43 #include "ui/gl/gl_switches.h" |
43 | 44 |
44 #if defined(TOOLKIT_GTK) | 45 #if defined(TOOLKIT_GTK) |
45 #include "ui/gfx/gtk_native_view_id_manager.h" | 46 #include "ui/gfx/gtk_native_view_id_manager.h" |
46 #endif | 47 #endif |
47 | 48 |
48 #if defined(OS_WIN) | 49 #if defined(OS_WIN) |
50 #include "base/win/windows_version.h" | |
51 #include "content/common/sandbox_win.h" | |
52 #include "content/public/common/sandboxed_process_launcher_delegate.h" | |
53 #include "sandbox/win/src/sandbox_policy.h" | |
49 #include "ui/surface/accelerated_surface_win.h" | 54 #include "ui/surface/accelerated_surface_win.h" |
50 #endif | 55 #endif |
51 | 56 |
52 namespace content { | 57 namespace content { |
53 | 58 |
54 bool GpuProcessHost::gpu_enabled_ = true; | 59 bool GpuProcessHost::gpu_enabled_ = true; |
55 bool GpuProcessHost::hardware_gpu_enabled_ = true; | 60 bool GpuProcessHost::hardware_gpu_enabled_ = true; |
56 | 61 |
57 namespace { | 62 namespace { |
58 | 63 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
156 int surface_id, | 161 int surface_id, |
157 uint64 surface_handle, | 162 uint64 surface_handle, |
158 bool alive, | 163 bool alive, |
159 base::TimeTicks timebase, | 164 base::TimeTicks timebase, |
160 base::TimeDelta interval) { | 165 base::TimeDelta interval) { |
161 AcceleratedSurfaceBuffersSwappedCompletedForGPU(host_id, route_id, | 166 AcceleratedSurfaceBuffersSwappedCompletedForGPU(host_id, route_id, |
162 alive, surface_handle); | 167 alive, surface_handle); |
163 AcceleratedSurfaceBuffersSwappedCompletedForRenderer(surface_id, timebase, | 168 AcceleratedSurfaceBuffersSwappedCompletedForRenderer(surface_id, timebase, |
164 interval); | 169 interval); |
165 } | 170 } |
171 | |
172 // NOTE: changes to this class need to be reviewed by the security team. | |
173 class GpuSandboxedProcessLauncherDelegate | |
174 : public SandboxedProcessLauncherDelegate { | |
175 public: | |
176 explicit GpuSandboxedProcessLauncherDelegate(CommandLine* cmd_line) | |
177 : cmd_line_(cmd_line) {} | |
178 virtual ~GpuSandboxedProcessLauncherDelegate() {} | |
179 | |
180 virtual void PreSandbox(bool* disable_default_policy, | |
181 base::FilePath* exposed_dir) { | |
182 *disable_default_policy = true; | |
183 } | |
cpu_(ooo_6.6-7.5)
2013/03/19 21:27:42
OVERRIDE
same below
| |
184 | |
185 // For the GPU process we gotten as far as USER_LIMITED. The next level | |
186 // which is USER_RESTRICTED breaks both the DirectX backend and the OpenGL | |
187 // backend. Note that the GPU process is connected to the interactive | |
188 // desktop. | |
189 // TODO(cpu): Lock down the sandbox more if possible. | |
190 virtual void PreSpawnTarget(sandbox::TargetPolicy* policy, | |
191 bool* success) { | |
192 if (base::win::GetVersion() > base::win::VERSION_XP) { | |
193 if (cmd_line_->GetSwitchValueASCII(switches::kUseGL) == | |
194 gfx::kGLImplementationDesktopName) { | |
195 // Open GL path. | |
196 policy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS, | |
197 sandbox::USER_LIMITED); | |
198 SetJobLevel(*cmd_line_, sandbox::JOB_UNPROTECTED, 0, policy); | |
199 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); | |
200 } else { | |
201 if (cmd_line_->GetSwitchValueASCII(switches::kUseGL) == | |
202 gfx::kGLImplementationSwiftShaderName || | |
203 cmd_line_->HasSwitch(switches::kReduceGpuSandbox) || | |
204 cmd_line_->HasSwitch(switches::kDisableImageTransportSurface)) { | |
205 // Swiftshader path. | |
206 policy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS, | |
207 sandbox::USER_LIMITED); | |
208 } else { | |
209 // Angle + DirectX path. | |
210 policy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS, | |
211 sandbox::USER_RESTRICTED); | |
212 // This is a trick to keep the GPU out of low-integrity processes. It | |
213 // starts at low-integrity for UIPI to work, then drops below | |
214 // low-integrity after warm-up. | |
215 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_UNTRUSTED); | |
216 } | |
217 | |
218 // UI restrictions break when we access Windows from outside our job. | |
219 // However, we don't want a proxy window in this process because it can | |
220 // introduce deadlocks where the renderer blocks on the gpu, which in | |
221 // turn blocks on the browser UI thread. So, instead we forgo a window | |
222 // message pump entirely and just add job restrictions to prevent child | |
223 // processes. | |
224 SetJobLevel(*cmd_line_, | |
225 sandbox::JOB_LIMITED_USER, | |
226 JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | | |
227 JOB_OBJECT_UILIMIT_DESKTOP | | |
228 JOB_OBJECT_UILIMIT_EXITWINDOWS | | |
229 JOB_OBJECT_UILIMIT_DISPLAYSETTINGS, | |
230 policy); | |
231 | |
232 policy->SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); | |
233 } | |
234 } else { | |
235 SetJobLevel(*cmd_line_, sandbox::JOB_UNPROTECTED, 0, policy); | |
236 policy->SetTokenLevel(sandbox::USER_UNPROTECTED, | |
237 sandbox::USER_LIMITED); | |
238 } | |
239 | |
240 // Allow the server side of GPU sockets, which are pipes that have | |
241 // the "chrome.gpu" namespace and an arbitrary suffix. | |
242 sandbox::ResultCode result = policy->AddRule( | |
243 sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, | |
244 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, | |
245 L"\\\\.\\pipe\\chrome.gpu.*"); | |
246 if (result != sandbox::SBOX_ALL_OK) { | |
247 *success = false; | |
248 return; | |
249 } | |
250 | |
251 #ifdef USE_AURA | |
252 // GPU also needs to add sections to the browser for aura | |
253 // TODO(jschuh): refactor the GPU channel to remove this. crbug.com/128786 | |
254 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES, | |
255 sandbox::TargetPolicy::HANDLES_DUP_BROKER, | |
256 L"Section"); | |
257 if (result != sandbox::SBOX_ALL_OK) { | |
258 *success = false; | |
259 return; | |
260 } | |
261 #endif | |
262 | |
263 if (cmd_line_->HasSwitch(switches::kEnableLogging)) { | |
264 string16 log_file_path = logging::GetLogFileFullPath(); | |
265 if (!log_file_path.empty()) { | |
266 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, | |
267 sandbox::TargetPolicy::FILES_ALLOW_ANY, | |
268 log_file_path.c_str()); | |
269 if (result != sandbox::SBOX_ALL_OK) { | |
270 *success = false; | |
271 return; | |
272 } | |
273 } | |
274 } | |
275 } | |
276 | |
277 private: | |
278 CommandLine* cmd_line_; | |
279 }; | |
166 #endif // defined(OS_WIN) | 280 #endif // defined(OS_WIN) |
167 | 281 |
168 } // anonymous namespace | 282 } // anonymous namespace |
169 | 283 |
170 #if defined(TOOLKIT_GTK) | 284 #if defined(TOOLKIT_GTK) |
171 // Used to put a lock on surfaces so that the window to which the GPU | 285 // Used to put a lock on surfaces so that the window to which the GPU |
172 // process is drawing to doesn't disappear while it is drawing when | 286 // process is drawing to doesn't disappear while it is drawing when |
173 // a WebContents is closed. | 287 // a WebContents is closed. |
174 class GpuProcessHost::SurfaceRef { | 288 class GpuProcessHost::SurfaceRef { |
175 public: | 289 public: |
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1054 switches::kDisableSeccompFilterSandbox, | 1168 switches::kDisableSeccompFilterSandbox, |
1055 switches::kEnableGpuSandbox, | 1169 switches::kEnableGpuSandbox, |
1056 switches::kEnableLogging, | 1170 switches::kEnableLogging, |
1057 switches::kEnableVirtualGLContexts, | 1171 switches::kEnableVirtualGLContexts, |
1058 switches::kGpuStartupDialog, | 1172 switches::kGpuStartupDialog, |
1059 switches::kLoggingLevel, | 1173 switches::kLoggingLevel, |
1060 switches::kNoSandbox, | 1174 switches::kNoSandbox, |
1061 switches::kReduceGpuSandbox, | 1175 switches::kReduceGpuSandbox, |
1062 switches::kTestGLLib, | 1176 switches::kTestGLLib, |
1063 switches::kTraceStartup, | 1177 switches::kTraceStartup, |
1178 switches::kUseExynosVda, | |
1064 switches::kV, | 1179 switches::kV, |
1065 switches::kVModule, | 1180 switches::kVModule, |
1066 #if defined(OS_MACOSX) | 1181 #if defined(OS_MACOSX) |
1067 switches::kEnableSandboxLogging, | 1182 switches::kEnableSandboxLogging, |
1068 #endif | 1183 #endif |
1069 #if defined(USE_AURA) | 1184 #if defined(USE_AURA) |
1070 switches::kUIPrioritizeInGpuProcess, | 1185 switches::kUIPrioritizeInGpuProcess, |
1071 #endif | 1186 #endif |
1072 switches::kUseExynosVda, | |
1073 }; | 1187 }; |
1074 cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames, | 1188 cmd_line->CopySwitchesFrom(browser_command_line, kSwitchNames, |
1075 arraysize(kSwitchNames)); | 1189 arraysize(kSwitchNames)); |
1076 cmd_line->CopySwitchesFrom( | 1190 cmd_line->CopySwitchesFrom( |
1077 browser_command_line, switches::kGpuSwitches, switches::kNumGpuSwitches); | 1191 browser_command_line, switches::kGpuSwitches, switches::kNumGpuSwitches); |
1078 cmd_line->CopySwitchesFrom( | 1192 cmd_line->CopySwitchesFrom( |
1079 browser_command_line, switches::kGLSwitchesCopiedFromGpuProcessHost, | 1193 browser_command_line, switches::kGLSwitchesCopiedFromGpuProcessHost, |
1080 switches::kGLSwitchesCopiedFromGpuProcessHostNumSwitches); | 1194 switches::kGLSwitchesCopiedFromGpuProcessHostNumSwitches); |
1081 | 1195 |
1082 GetContentClient()->browser()->AppendExtraCommandLineSwitches( | 1196 GetContentClient()->browser()->AppendExtraCommandLineSwitches( |
1083 cmd_line, process_->GetData().id); | 1197 cmd_line, process_->GetData().id); |
1084 | 1198 |
1085 GpuDataManagerImpl::GetInstance()->AppendGpuCommandLine(cmd_line); | 1199 GpuDataManagerImpl::GetInstance()->AppendGpuCommandLine(cmd_line); |
1086 | 1200 |
1087 if (cmd_line->HasSwitch(switches::kUseGL)) { | 1201 if (cmd_line->HasSwitch(switches::kUseGL)) { |
1088 software_rendering_ = | 1202 software_rendering_ = |
1089 (cmd_line->GetSwitchValueASCII(switches::kUseGL) == "swiftshader"); | 1203 (cmd_line->GetSwitchValueASCII(switches::kUseGL) == "swiftshader"); |
1090 } | 1204 } |
1091 | 1205 |
1092 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessSoftwareRendering", software_rendering_); | 1206 UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessSoftwareRendering", software_rendering_); |
1093 | 1207 |
1094 #if defined(OS_WIN) | |
1095 // Make GoogleDesktopNetwork3.dll think that the GPU process is a renderer | |
1096 // process so the DLL unloads itself. http://crbug/129884 | |
1097 cmd_line->AppendSwitchASCII("ignored", " --type=renderer "); | |
1098 #endif | |
1099 | |
1100 // If specified, prepend a launcher program to the command line. | 1208 // If specified, prepend a launcher program to the command line. |
1101 if (!gpu_launcher.empty()) | 1209 if (!gpu_launcher.empty()) |
1102 cmd_line->PrependWrapper(gpu_launcher); | 1210 cmd_line->PrependWrapper(gpu_launcher); |
1103 | 1211 |
1104 process_->Launch( | 1212 process_->Launch( |
1105 #if defined(OS_WIN) | 1213 #if defined(OS_WIN) |
1106 base::FilePath(), | 1214 new GpuSandboxedProcessLauncherDelegate(cmd_line), |
1107 #elif defined(OS_POSIX) | 1215 #elif defined(OS_POSIX) |
1108 false, | 1216 false, |
1109 base::EnvironmentVector(), | 1217 base::EnvironmentVector(), |
1110 #endif | 1218 #endif |
1111 cmd_line); | 1219 cmd_line); |
1112 process_launched_ = true; | 1220 process_launched_ = true; |
1113 | 1221 |
1114 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents", | 1222 UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents", |
1115 LAUNCHED, GPU_PROCESS_LIFETIME_EVENT_MAX); | 1223 LAUNCHED, GPU_PROCESS_LIFETIME_EVENT_MAX); |
1116 return true; | 1224 return true; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1181 TRACE_EVENT0("gpu", "GpuProcessHost::OnCacheShader"); | 1289 TRACE_EVENT0("gpu", "GpuProcessHost::OnCacheShader"); |
1182 ClientIdToShaderCacheMap::iterator iter = | 1290 ClientIdToShaderCacheMap::iterator iter = |
1183 client_id_to_shader_cache_.find(client_id); | 1291 client_id_to_shader_cache_.find(client_id); |
1184 // If the cache doesn't exist then this is an off the record profile. | 1292 // If the cache doesn't exist then this is an off the record profile. |
1185 if (iter == client_id_to_shader_cache_.end()) | 1293 if (iter == client_id_to_shader_cache_.end()) |
1186 return; | 1294 return; |
1187 iter->second->Cache(GetShaderPrefixKey() + ":" + key, shader); | 1295 iter->second->Cache(GetShaderPrefixKey() + ":" + key, shader); |
1188 } | 1296 } |
1189 | 1297 |
1190 } // namespace content | 1298 } // namespace content |
OLD | NEW |