| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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/browser/sandbox_policy.h" | 5 #include "chrome/browser/sandbox_policy.h" |
| 6 | 6 |
| 7 #include "app/win_util.h" | 7 #include "app/win_util.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/debug_util.h" | 9 #include "base/debug_util.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/path_service.h" | 12 #include "base/path_service.h" |
| 13 #include "base/process_util.h" | 13 #include "base/process_util.h" |
| 14 #include "base/registry.h" | 14 #include "base/registry.h" |
| 15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
| 16 #include "base/win_util.h" | 16 #include "base/win_util.h" |
| 17 #include "chrome/browser/browser_process.h" | 17 #include "chrome/browser/browser_process.h" |
| 18 #include "chrome/common/child_process_info.h" | 18 #include "chrome/common/child_process_info.h" |
| 19 #include "chrome/common/chrome_constants.h" | 19 #include "chrome/common/chrome_constants.h" |
| 20 #include "chrome/common/chrome_paths.h" | 20 #include "chrome/common/chrome_paths.h" |
| 21 #include "chrome/common/chrome_switches.h" | 21 #include "chrome/common/chrome_switches.h" |
| 22 #include "chrome/common/debug_flags.h" | 22 #include "chrome/common/debug_flags.h" |
| 23 #include "chrome/common/ipc_logging.h" | 23 #include "chrome/common/ipc_logging.h" |
| 24 #include "chrome/common/notification_service.h" | 24 #include "chrome/common/notification_service.h" |
| 25 #include "sandbox/src/sandbox.h" | 25 #include "sandbox/src/sandbox.h" |
| 26 #include "webkit/glue/plugins/plugin_list.h" | 26 #include "webkit/glue/plugins/plugin_list.h" |
| 27 | 27 |
| 28 namespace { | 28 namespace { |
| 29 | 29 |
| 30 const wchar_t* const kDesktopName = L"ChromeRendererDesktop"; | |
| 31 | |
| 32 // The DLLs listed here are known (or under strong suspicion) of causing crashes | 30 // The DLLs listed here are known (or under strong suspicion) of causing crashes |
| 33 // when they are loaded in the renderer. | 31 // when they are loaded in the renderer. |
| 34 const wchar_t* const kTroublesomeDlls[] = { | 32 const wchar_t* const kTroublesomeDlls[] = { |
| 35 L"adialhk.dll", // Kaspersky Internet Security. | 33 L"adialhk.dll", // Kaspersky Internet Security. |
| 36 L"acpiz.dll", // Unknown. | 34 L"acpiz.dll", // Unknown. |
| 37 L"avgrsstx.dll", // AVG 8. | 35 L"avgrsstx.dll", // AVG 8. |
| 38 L"btkeyind.dll", // Widcomm Bluetooth. | 36 L"btkeyind.dll", // Widcomm Bluetooth. |
| 39 L"cmcsyshk.dll", // CMC Internet Security. | 37 L"cmcsyshk.dll", // CMC Internet Security. |
| 40 L"dockshellhook.dll", // Stardock Objectdock. | 38 L"dockshellhook.dll", // Stardock Objectdock. |
| 41 L"GoogleDesktopNetwork3.DLL", // Google Desktop Search v5. | 39 L"GoogleDesktopNetwork3.DLL", // Google Desktop Search v5. |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 case PLUGIN_GROUP_UNTRUSTED: | 306 case PLUGIN_GROUP_UNTRUSTED: |
| 309 return ApplyPolicyForUntrustedPlugin(policy); | 307 return ApplyPolicyForUntrustedPlugin(policy); |
| 310 default: | 308 default: |
| 311 NOTREACHED(); | 309 NOTREACHED(); |
| 312 break; | 310 break; |
| 313 } | 311 } |
| 314 | 312 |
| 315 return false; | 313 return false; |
| 316 } | 314 } |
| 317 | 315 |
| 318 void AddPolicyForRenderer(HDESK desktop, sandbox::TargetPolicy* policy) { | 316 void AddPolicyForRenderer(sandbox::TargetPolicy* policy, |
| 317 bool* on_sandbox_desktop) { |
| 319 policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0); | 318 policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0); |
| 320 | 319 |
| 321 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED; | 320 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED; |
| 322 if (win_util::GetWinVersion() > win_util::WINVERSION_XP) { | 321 if (win_util::GetWinVersion() > win_util::WINVERSION_XP) { |
| 323 // On 2003/Vista the initial token has to be restricted if the main | 322 // On 2003/Vista the initial token has to be restricted if the main |
| 324 // token is restricted. | 323 // token is restricted. |
| 325 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS; | 324 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS; |
| 326 } | 325 } |
| 327 | 326 |
| 328 policy->SetTokenLevel(initial_token, sandbox::USER_LOCKDOWN); | 327 policy->SetTokenLevel(initial_token, sandbox::USER_LOCKDOWN); |
| 329 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); | 328 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); |
| 330 | 329 |
| 331 if (desktop) { | 330 bool use_winsta = !CommandLine::ForCurrentProcess()->HasSwitch( |
| 332 policy->SetDesktop(kDesktopName); | 331 switches::kDisableAltWinstation); |
| 332 |
| 333 if (sandbox::SBOX_ALL_OK == policy->SetAlternateDesktop(use_winsta)) { |
| 334 *on_sandbox_desktop = true; |
| 333 } else { | 335 } else { |
| 336 *on_sandbox_desktop = false; |
| 334 DLOG(WARNING) << "Failed to apply desktop security to the renderer"; | 337 DLOG(WARNING) << "Failed to apply desktop security to the renderer"; |
| 335 } | 338 } |
| 336 | 339 |
| 337 AddDllEvictionPolicy(policy); | 340 AddDllEvictionPolicy(policy); |
| 338 } | 341 } |
| 339 | 342 |
| 340 } // namespace | 343 } // namespace |
| 341 | 344 |
| 342 namespace sandbox { | 345 namespace sandbox { |
| 343 | 346 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 } | 387 } |
| 385 | 388 |
| 386 // spawn the child process in the sandbox | 389 // spawn the child process in the sandbox |
| 387 sandbox::BrokerServices* broker_service = | 390 sandbox::BrokerServices* broker_service = |
| 388 g_browser_process->broker_services(); | 391 g_browser_process->broker_services(); |
| 389 | 392 |
| 390 sandbox::ResultCode result; | 393 sandbox::ResultCode result; |
| 391 PROCESS_INFORMATION target = {0}; | 394 PROCESS_INFORMATION target = {0}; |
| 392 sandbox::TargetPolicy* policy = broker_service->CreatePolicy(); | 395 sandbox::TargetPolicy* policy = broker_service->CreatePolicy(); |
| 393 | 396 |
| 394 HDESK desktop = NULL; | 397 bool on_sandbox_desktop = false; |
| 395 if (type == ChildProcessInfo::PLUGIN_PROCESS) { | 398 if (type == ChildProcessInfo::PLUGIN_PROCESS) { |
| 396 if (!AddPolicyForPlugin(cmd_line, policy)) | 399 if (!AddPolicyForPlugin(cmd_line, policy)) |
| 397 return 0; | 400 return 0; |
| 398 } else { | 401 } else { |
| 399 desktop = CreateDesktop( | 402 AddPolicyForRenderer(policy, &on_sandbox_desktop); |
| 400 kDesktopName, NULL, NULL, 0, DESKTOP_CREATEWINDOW, NULL); | |
| 401 AddPolicyForRenderer(desktop, policy); | |
| 402 } | 403 } |
| 403 | 404 |
| 404 if (!exposed_dir.empty()) { | 405 if (!exposed_dir.empty()) { |
| 405 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, | 406 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, |
| 406 sandbox::TargetPolicy::FILES_ALLOW_ANY, | 407 sandbox::TargetPolicy::FILES_ALLOW_ANY, |
| 407 exposed_dir.ToWStringHack().c_str()); | 408 exposed_dir.ToWStringHack().c_str()); |
| 408 if (result != sandbox::SBOX_ALL_OK) | 409 if (result != sandbox::SBOX_ALL_OK) |
| 409 return 0; | 410 return 0; |
| 410 | 411 |
| 411 FilePath exposed_files = exposed_dir.AppendASCII("*"); | 412 FilePath exposed_files = exposed_dir.AppendASCII("*"); |
| 412 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, | 413 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, |
| 413 sandbox::TargetPolicy::FILES_ALLOW_ANY, | 414 sandbox::TargetPolicy::FILES_ALLOW_ANY, |
| 414 exposed_files.ToWStringHack().c_str()); | 415 exposed_files.ToWStringHack().c_str()); |
| 415 if (result != sandbox::SBOX_ALL_OK) | 416 if (result != sandbox::SBOX_ALL_OK) |
| 416 return 0; | 417 return 0; |
| 417 } | 418 } |
| 418 | 419 |
| 419 if (!AddGenericPolicy(policy)) { | 420 if (!AddGenericPolicy(policy)) { |
| 420 NOTREACHED(); | 421 NOTREACHED(); |
| 421 if (desktop) | |
| 422 CloseDesktop(desktop); | |
| 423 return 0; | 422 return 0; |
| 424 } | 423 } |
| 425 | 424 |
| 426 result = broker_service->SpawnTarget( | 425 result = broker_service->SpawnTarget( |
| 427 cmd_line->program().c_str(), | 426 cmd_line->program().c_str(), |
| 428 cmd_line->command_line_string().c_str(), | 427 cmd_line->command_line_string().c_str(), |
| 429 policy, &target); | 428 policy, &target); |
| 430 policy->Release(); | 429 policy->Release(); |
| 431 | 430 |
| 432 if (desktop) | |
| 433 CloseDesktop(desktop); | |
| 434 | |
| 435 if (sandbox::SBOX_ALL_OK != result) | 431 if (sandbox::SBOX_ALL_OK != result) |
| 436 return 0; | 432 return 0; |
| 437 | 433 |
| 438 if (type == ChildProcessInfo::RENDER_PROCESS) { | 434 if (type == ChildProcessInfo::RENDER_PROCESS) { |
| 439 bool on_sandbox_desktop = (desktop != NULL); | |
| 440 NotificationService::current()->Notify( | 435 NotificationService::current()->Notify( |
| 441 NotificationType::RENDERER_PROCESS_IN_SBOX, | 436 NotificationType::RENDERER_PROCESS_IN_SBOX, |
| 442 NotificationService::AllSources(), | 437 NotificationService::AllSources(), |
| 443 Details<bool>(&on_sandbox_desktop)); | 438 Details<bool>(&on_sandbox_desktop)); |
| 444 } | 439 } |
| 445 | 440 |
| 446 ResumeThread(target.hThread); | 441 ResumeThread(target.hThread); |
| 447 CloseHandle(target.hThread); | 442 CloseHandle(target.hThread); |
| 448 process = target.hProcess; | 443 process = target.hProcess; |
| 449 | 444 |
| 450 // Help the process a little. It can't start the debugger by itself if | 445 // Help the process a little. It can't start the debugger by itself if |
| 451 // the process is in a sandbox. | 446 // the process is in a sandbox. |
| 452 if (child_needs_help) | 447 if (child_needs_help) |
| 453 DebugUtil::SpawnDebuggerOnProcess(target.dwProcessId); | 448 DebugUtil::SpawnDebuggerOnProcess(target.dwProcessId); |
| 454 | 449 |
| 455 return process; | 450 return process; |
| 456 } | 451 } |
| 457 | 452 |
| 458 } // namespace sandbox | 453 } // namespace sandbox |
| OLD | NEW |