OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/common/sandbox_policy.h" | 5 #include "chrome/common/sandbox_policy.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "app/win_util.h" | 9 #include "app/win_util.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/debug_util.h" | 11 #include "base/debug_util.h" |
12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
15 #include "base/process_util.h" | 15 #include "base/process_util.h" |
| 16 #include "base/stringprintf.h" |
| 17 #include "base/string_number_conversions.h" |
16 #include "base/string_util.h" | 18 #include "base/string_util.h" |
17 #include "base/trace_event.h" | 19 #include "base/trace_event.h" |
18 #include "base/win_util.h" | 20 #include "base/win_util.h" |
19 #include "chrome/common/child_process_info.h" | 21 #include "chrome/common/child_process_info.h" |
20 #include "chrome/common/chrome_constants.h" | 22 #include "chrome/common/chrome_constants.h" |
21 #include "chrome/common/chrome_paths.h" | 23 #include "chrome/common/chrome_paths.h" |
22 #include "chrome/common/chrome_switches.h" | 24 #include "chrome/common/chrome_switches.h" |
23 #include "chrome/common/debug_flags.h" | 25 #include "chrome/common/debug_flags.h" |
24 #include "sandbox/src/sandbox.h" | 26 #include "sandbox/src/sandbox.h" |
25 | 27 |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 // AppData itself. | 295 // AppData itself. |
294 if (!AddDirectory(base::DIR_APP_DATA, L"..", false, | 296 if (!AddDirectory(base::DIR_APP_DATA, L"..", false, |
295 sandbox::TargetPolicy::FILES_ALLOW_READONLY, | 297 sandbox::TargetPolicy::FILES_ALLOW_READONLY, |
296 policy)) | 298 policy)) |
297 return false; | 299 return false; |
298 } | 300 } |
299 | 301 |
300 return true; | 302 return true; |
301 } | 303 } |
302 | 304 |
| 305 // Launches the privileged flash broker, used when flash is sandboxed. |
| 306 // The broker is the same flash dll, except that it uses a different |
| 307 // entrypoint (BrokerMain) and it is hosted in windows' generic surrogate |
| 308 // process rundll32. After launching the broker we need to pass to |
| 309 // the flash plugin the process id of the broker via the command line |
| 310 // using --flash-broker=pid. |
| 311 // More info about rundll32 at http://support.microsoft.com/kb/164787. |
| 312 bool LoadFlashBroker(const FilePath& plugin_path, CommandLine* cmd_line) { |
| 313 FilePath rundll; |
| 314 if (!PathService::Get(base::DIR_SYSTEM, &rundll)) |
| 315 return false; |
| 316 rundll = rundll.AppendASCII("rundll32.exe"); |
| 317 // Rundll32 cannot handle paths with spaces, so we use the short path. |
| 318 wchar_t short_path[MAX_PATH]; |
| 319 if (0 == ::GetShortPathNameW(plugin_path.value().c_str(), |
| 320 short_path, arraysize(short_path))) |
| 321 return false; |
| 322 std::wstring cmd_final = |
| 323 base::StringPrintf(L"%ls %ls,BrokerMain browser=chrome", |
| 324 rundll.value().c_str(), |
| 325 short_path); |
| 326 base::ProcessHandle process; |
| 327 if (!base::LaunchApp(cmd_final, false, true, &process)) |
| 328 return false; |
| 329 |
| 330 cmd_line->AppendSwitchASCII("flash-broker", |
| 331 base::Int64ToString(::GetProcessId(process))); |
| 332 ::CloseHandle(process); |
| 333 return true; |
| 334 } |
| 335 |
303 // Creates a sandbox for the built-in flash plugin running in a restricted | 336 // Creates a sandbox for the built-in flash plugin running in a restricted |
304 // environment. This is a work in progress and for the time being do not | 337 // environment. This is a work in progress and for the time being do not |
305 // pay attention to the duplication between this function and the above | 338 // pay attention to the duplication between this function and the above |
306 // function. For more information see bug 50796. | 339 // function. For more information see bug 50796. |
307 bool ApplyPolicyForBuiltInFlashPlugin(sandbox::TargetPolicy* policy) { | 340 bool ApplyPolicyForBuiltInFlashPlugin(sandbox::TargetPolicy* policy) { |
308 // TODO(cpu): Lock down the job level more. | 341 // TODO(cpu): Lock down the job level more. |
309 policy->SetJobLevel(sandbox::JOB_UNPROTECTED, 0); | 342 policy->SetJobLevel(sandbox::JOB_UNPROTECTED, 0); |
310 | 343 |
311 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED; | 344 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED; |
| 345 |
312 if (win_util::GetWinVersion() > win_util::WINVERSION_XP) | 346 if (win_util::GetWinVersion() > win_util::WINVERSION_XP) |
313 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS; | 347 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS; |
| 348 |
314 policy->SetTokenLevel(initial_token, sandbox::USER_LIMITED); | 349 policy->SetTokenLevel(initial_token, sandbox::USER_LIMITED); |
315 | 350 |
316 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); | 351 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); |
317 | 352 |
318 // TODO(cpu): Proxy registry access and remove these policies. | 353 // TODO(cpu): Proxy registry access and remove these policies. |
319 if (!AddKeyAndSubkeys(L"HKEY_CURRENT_USER\\SOFTWARE\\ADOBE", | 354 if (!AddKeyAndSubkeys(L"HKEY_CURRENT_USER\\SOFTWARE\\ADOBE", |
320 sandbox::TargetPolicy::REG_ALLOW_ANY, | 355 sandbox::TargetPolicy::REG_ALLOW_ANY, |
321 policy)) | 356 policy)) |
322 return false; | 357 return false; |
323 | 358 |
324 if (!AddKeyAndSubkeys(L"HKEY_CURRENT_USER\\SOFTWARE\\MACROMEDIA", | 359 if (!AddKeyAndSubkeys(L"HKEY_CURRENT_USER\\SOFTWARE\\MACROMEDIA", |
325 sandbox::TargetPolicy::REG_ALLOW_ANY, | 360 sandbox::TargetPolicy::REG_ALLOW_ANY, |
326 policy)) | 361 policy)) |
327 return false; | 362 return false; |
328 | |
329 // Use a different data folder for flash data. This needs to be | |
330 // reverted once we stop the experiments. | |
331 FilePath flash_path; | |
332 PathService::Get(chrome::DIR_USER_DATA, &flash_path); | |
333 flash_path = flash_path.AppendASCII("swflash"); | |
334 ::SetEnvironmentVariableW(L"CHROME_FLASH_ROOT", | |
335 flash_path.ToWStringHack().c_str()); | |
336 return true; | 363 return true; |
337 } | 364 } |
338 | 365 |
339 // Adds the custom policy rules for a given plugin. |trusted_plugins| contains | 366 // Adds the custom policy rules for a given plugin. |trusted_plugins| contains |
340 // the comma separate list of plugin dll names that should not be sandboxed. | 367 // the comma separate list of plugin dll names that should not be sandboxed. |
341 bool AddPolicyForPlugin(const CommandLine* cmd_line, | 368 bool AddPolicyForPlugin(CommandLine* cmd_line, |
342 sandbox::TargetPolicy* policy) { | 369 sandbox::TargetPolicy* policy) { |
343 std::wstring plugin_dll = cmd_line-> | 370 std::wstring plugin_dll = cmd_line-> |
344 GetSwitchValueNative(switches::kPluginPath); | 371 GetSwitchValueNative(switches::kPluginPath); |
345 std::wstring trusted_plugins = CommandLine::ForCurrentProcess()-> | 372 std::wstring trusted_plugins = CommandLine::ForCurrentProcess()-> |
346 GetSwitchValueNative(switches::kTrustedPlugins); | 373 GetSwitchValueNative(switches::kTrustedPlugins); |
347 // Add the policy for the pipes. | 374 // Add the policy for the pipes. |
348 sandbox::ResultCode result = sandbox::SBOX_ALL_OK; | 375 sandbox::ResultCode result = sandbox::SBOX_ALL_OK; |
349 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, | 376 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, |
350 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, | 377 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, |
351 L"\\\\.\\pipe\\chrome.*"); | 378 L"\\\\.\\pipe\\chrome.*"); |
352 if (result != sandbox::SBOX_ALL_OK) { | 379 if (result != sandbox::SBOX_ALL_OK) { |
353 NOTREACHED(); | 380 NOTREACHED(); |
354 return false; | 381 return false; |
355 } | 382 } |
356 | 383 |
357 // The built-in flash gets a custom, more restricted sandbox. | 384 // The built-in flash gets a custom, more restricted sandbox. |
358 FilePath builtin_flash; | 385 FilePath builtin_flash; |
359 if (PathService::Get(chrome::FILE_FLASH_PLUGIN, &builtin_flash)) { | 386 if (PathService::Get(chrome::FILE_FLASH_PLUGIN, &builtin_flash)) { |
360 FilePath plugin_path(plugin_dll); | 387 FilePath plugin_path(plugin_dll); |
361 if (plugin_path == builtin_flash) | 388 if (plugin_path == builtin_flash) { |
| 389 // Spawn the flash broker and apply sandbox policy. |
| 390 if (!LoadFlashBroker(plugin_path, cmd_line)) { |
| 391 // Could not start the broker, use a very weak policy instead. |
| 392 DLOG(WARNING) << "Failed to start flash broker"; |
| 393 return ApplyPolicyForTrustedPlugin(policy); |
| 394 } |
362 return ApplyPolicyForBuiltInFlashPlugin(policy); | 395 return ApplyPolicyForBuiltInFlashPlugin(policy); |
| 396 } |
363 } | 397 } |
364 | 398 |
365 PluginPolicyCategory policy_category = | 399 PluginPolicyCategory policy_category = |
366 GetPolicyCategoryForPlugin(plugin_dll, trusted_plugins); | 400 GetPolicyCategoryForPlugin(plugin_dll, trusted_plugins); |
367 | 401 |
368 switch (policy_category) { | 402 switch (policy_category) { |
369 case PLUGIN_GROUP_TRUSTED: | 403 case PLUGIN_GROUP_TRUSTED: |
370 return ApplyPolicyForTrustedPlugin(policy); | 404 return ApplyPolicyForTrustedPlugin(policy); |
371 case PLUGIN_GROUP_UNTRUSTED: | 405 case PLUGIN_GROUP_UNTRUSTED: |
372 return ApplyPolicyForUntrustedPlugin(policy); | 406 return ApplyPolicyForUntrustedPlugin(policy); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 | 578 |
545 // Help the process a little. It can't start the debugger by itself if | 579 // Help the process a little. It can't start the debugger by itself if |
546 // the process is in a sandbox. | 580 // the process is in a sandbox. |
547 if (child_needs_help) | 581 if (child_needs_help) |
548 DebugUtil::SpawnDebuggerOnProcess(target.dwProcessId); | 582 DebugUtil::SpawnDebuggerOnProcess(target.dwProcessId); |
549 | 583 |
550 return process; | 584 return process; |
551 } | 585 } |
552 | 586 |
553 } // namespace sandbox | 587 } // namespace sandbox |
OLD | NEW |