172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Use of this source code is governed by a BSD-style license that can be
306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// found in the LICENSE file.
406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "chrome/common/sandbox_policy.h"
606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include <string>
806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "base/command_line.h"
10513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/debug/debugger.h"
11513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/debug/trace_event.h"
1206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "base/file_util.h"
1306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "base/logging.h"
1406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "base/path_service.h"
1506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "base/process_util.h"
163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/stringprintf.h"
173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
1806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "base/string_util.h"
19731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/win/windows_version.h"
2006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "chrome/common/chrome_constants.h"
2106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "chrome/common/chrome_paths.h"
2206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "chrome/common/chrome_switches.h"
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/child_process_info.h"
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/debug_flags.h"
2506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "sandbox/src/sandbox.h"
2606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
2706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochstatic sandbox::BrokerServices* g_broker_services = NULL;
2806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
2906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochnamespace {
3006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
3106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// The DLLs listed here are known (or under strong suspicion) of causing crashes
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// when they are loaded in the renderer. Note: at runtime we generate short
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// versions of the dll name only if the dll has an extension.
3406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochconst wchar_t* const kTroublesomeDlls[] = {
3506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"adialhk.dll",                 // Kaspersky Internet Security.
3606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"acpiz.dll",                   // Unknown.
3706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"avgrsstx.dll",                // AVG 8.
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  L"babylonchromepi.dll",         // Babylon translator.
3906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"btkeyind.dll",                // Widcomm Bluetooth.
4006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"cmcsyshk.dll",                // CMC Internet Security.
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  L"cooliris.dll",                // CoolIris.
4206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"dockshellhook.dll",           // Stardock Objectdock.
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  L"googledesktopnetwork3.dll",   // Google Desktop Search v5.
4406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"fwhook.dll",                  // PC Tools Firewall Plus.
4506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"hookprocesscreation.dll",     // Blumentals Program protector.
4606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"hookterminateapis.dll",       // Blumentals and Cyberprinter.
4706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"hookprintapis.dll",           // Cyberprinter.
4806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"imon.dll",                    // NOD32 Antivirus.
4906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"ioloHL.dll",                  // Iolo (System Mechanic).
5006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"kloehk.dll",                  // Kaspersky Internet Security.
5106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"lawenforcer.dll",             // Spyware-Browser AntiSpyware (Spybro).
5206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"libdivx.dll",                 // DivX.
5306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"lvprcinj01.dll",              // Logitech QuickCam.
5406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"madchook.dll",                // Madshi (generic hooking library).
5506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"mdnsnsp.dll",                 // Bonjour.
5606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"moonsysh.dll",                // Moon Secure Antivirus.
5706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"npdivx32.dll",                // DivX.
5806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"npggNT.des",                  // GameGuard 2008.
5906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"npggNT.dll",                  // GameGuard (older).
6006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"oawatch.dll",                 // Online Armor.
6106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"pavhook.dll",                 // Panda Internet Security.
6206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"pavshook.dll",                // Panda Antivirus.
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  L"pavshookwow.dll",             // Panda Antivirus.
6406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"pctavhook.dll",               // PC Tools Antivirus.
6506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"pctgmhk.dll",                 // PC Tools Spyware Doctor.
6606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"prntrack.dll",                // Pharos Systems.
6706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"radhslib.dll",                // Radiant Naomi Internet Filter.
6806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"radprlib.dll",                // Radiant Naomi Internet Filter.
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  L"rapportnikko.dll",            // Trustware Rapport.
7006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"rlhook.dll",                  // Trustware Bufferzone.
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  L"rooksdol.dll",                // Trustware Rapport.
7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  L"rpchromebrowserrecordhelper.dll",  // RealPlayer.
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  L"rpmainbrowserrecordplugin.dll",    // RealPlayer.
7406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"r3hook.dll",                  // Kaspersky Internet Security.
7506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"sahook.dll",                  // McAfee Site Advisor.
7606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"sbrige.dll",                  // Unknown.
7706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"sc2hook.dll",                 // Supercopier 2.
7806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"sguard.dll",                  // Iolo (System Guard).
7906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"smum32.dll",                  // Spyware Doctor version 6.
8006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"smumhook.dll",                // Spyware Doctor version 5.
8106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"ssldivx.dll",                 // DivX.
8206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"syncor11.dll",                // SynthCore Midi interface.
8306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"systools.dll",                // Panda Antivirus.
8406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"tfwah.dll",                   // Threatfire (PC tools).
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  L"ycwebcamerasource.ax",        // Cyberlink Camera helper.
8606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"wblind.dll",                  // Stardock Object desktop.
8706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"wbhelp.dll",                  // Stardock Object desktop.
8806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  L"winstylerthemehelper.dll"     // Tuneup utilities 2006.
8906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch};
9006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
9106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochenum PluginPolicyCategory {
9206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  PLUGIN_GROUP_TRUSTED,
9306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  PLUGIN_GROUP_UNTRUSTED,
9406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch};
9506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
9606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Returns the policy category for the plugin dll.
9706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen MurdochPluginPolicyCategory GetPolicyCategoryForPlugin(
9806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    const std::wstring& dll,
9906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    const std::wstring& list) {
10006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::wstring filename = FilePath(dll).BaseName().value();
10106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::wstring plugin_dll = StringToLowerASCII(filename);
10206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::wstring trusted_plugins = StringToLowerASCII(list);
10306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
10406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  size_t pos = 0;
10506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  size_t end_item = 0;
10606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  while (end_item != std::wstring::npos) {
10706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    end_item = list.find(L",", pos);
10806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
10906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    size_t size_item = (end_item == std::wstring::npos) ? end_item :
11006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                                                          end_item - pos;
11106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    std::wstring item = list.substr(pos, size_item);
11206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    if (!item.empty() && item == plugin_dll)
11306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      return PLUGIN_GROUP_TRUSTED;
11406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
11506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    pos = end_item + 1;
11606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
11706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
11806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return PLUGIN_GROUP_UNTRUSTED;
11906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
12006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
12106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Adds the policy rules for the path and path\ with the semantic |access|.
12206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// If |children| is set to true, we need to add the wildcard rules to also
12306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// apply the rule to the subfiles and subfolders.
12406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochbool AddDirectory(int path, const wchar_t* sub_dir, bool children,
12506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                  sandbox::TargetPolicy::Semantics access,
12606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                  sandbox::TargetPolicy* policy) {
12721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  FilePath directory;
12806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!PathService::Get(path, &directory))
12906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
13006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
13106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (sub_dir) {
13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    directory = directory.Append(sub_dir);
13306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    file_util::AbsolutePath(&directory);
13406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
13506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
13606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  sandbox::ResultCode result;
13706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, access,
13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                           directory.value().c_str());
13906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (result != sandbox::SBOX_ALL_OK)
14006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
14106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  std::wstring directory_str = directory.value() + L"\\";
14306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (children)
14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    directory_str += L"*";
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Otherwise, add the version of the path that ends with a separator.
14606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
14706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, access,
14821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                           directory_str.c_str());
14906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (result != sandbox::SBOX_ALL_OK)
15006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
15106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
15206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return true;
15306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
15406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
15506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Adds the policy rules for the path and path\* with the semantic |access|.
15606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// We need to add the wildcard rules to also apply the rule to the subkeys.
15706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochbool AddKeyAndSubkeys(std::wstring key,
15806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                      sandbox::TargetPolicy::Semantics access,
15906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                      sandbox::TargetPolicy* policy) {
16006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  sandbox::ResultCode result;
16106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_REGISTRY, access,
16206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                           key.c_str());
16306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (result != sandbox::SBOX_ALL_OK)
16406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
16506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
16606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  key += L"\\*";
16706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_REGISTRY, access,
16806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                           key.c_str());
16906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (result != sandbox::SBOX_ALL_OK)
17006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
17106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
17206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return true;
17306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
17406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Compares the loaded |module| file name matches |module_name|.
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool IsExpandedModuleName(HMODULE module, const wchar_t* module_name) {
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  wchar_t path[MAX_PATH];
178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DWORD sz = ::GetModuleFileNameW(module, path, arraysize(path));
179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if ((sz == arraysize(path)) || (sz == 0)) {
180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // XP does not set the last error properly, so we bail out anyway.
181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return false;
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!::GetLongPathName(path, path, arraysize(path)))
184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return false;
185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath fname(path);
186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return (fname.BaseName().value() == module_name);
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Adds a single dll by |module_name| into the |policy| blacklist.
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// To minimize the list we only add an unload policy only if the dll is
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// also loaded in this process. All the injected dlls of interest do this.
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BlacklistAddOneDll(const wchar_t* module_name,
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        sandbox::TargetPolicy* policy) {
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  HMODULE module = ::GetModuleHandleW(module_name);
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!module) {
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // The module could have been loaded with a 8.3 short name. We use
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // the most common case: 'thelongname.dll' becomes 'thelon~1.dll'.
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::wstring name(module_name);
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    size_t period = name.rfind(L'.');
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK_NE(std::string::npos, period);
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK_LE(3U, (name.size() - period));
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (period <= 8)
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::wstring alt_name = name.substr(0, 6) + L"~1";
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    alt_name += name.substr(period, name.size());
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    module = ::GetModuleHandleW(alt_name.c_str());
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!module)
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // We found it, but because it only has 6 significant letters, we
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // want to make sure it is the right one.
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!IsExpandedModuleName(module, module_name))
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Found a match. We add both forms to the policy.
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    policy->AddDllToUnload(alt_name.c_str());
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  policy->AddDllToUnload(module_name);
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  VLOG(1) << "dll to unload found: " << module_name;
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return;
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
22106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Adds policy rules for unloaded the known dlls that cause chrome to crash.
22206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Eviction of injected DLLs is done by the sandbox so that the injected module
22306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// does not get a chance to execute any code.
22406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochvoid AddDllEvictionPolicy(sandbox::TargetPolicy* policy) {
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (int ix = 0; ix != arraysize(kTroublesomeDlls); ++ix)
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BlacklistAddOneDll(kTroublesomeDlls[ix], policy);
22706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
22806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
22906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Adds the generic policy rules to a sandbox TargetPolicy.
23006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochbool AddGenericPolicy(sandbox::TargetPolicy* policy) {
23106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  sandbox::ResultCode result;
23206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
23306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Add the policy for the pipes
23406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
23506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                           sandbox::TargetPolicy::FILES_ALLOW_ANY,
23606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                           L"\\??\\pipe\\chrome.*");
23706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (result != sandbox::SBOX_ALL_OK)
23806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
23906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
24006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES,
24106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                           sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY,
24206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                           L"\\\\.\\pipe\\chrome.nacl.*");
24306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (result != sandbox::SBOX_ALL_OK)
24406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
24506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
24606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Add the policy for debug message only in debug
24706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#ifndef NDEBUG
24821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  FilePath app_dir;
24921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (!PathService::Get(chrome::DIR_APP, &app_dir))
25006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
2513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  wchar_t long_path_buf[MAX_PATH];
2533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  DWORD long_path_return_value = GetLongPathName(app_dir.value().c_str(),
2543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                                 long_path_buf,
2553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                                 MAX_PATH);
2563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  if (long_path_return_value == 0 || long_path_return_value >= MAX_PATH)
25706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
2583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen
2593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  string16 debug_message(long_path_buf);
26006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  file_util::AppendToPath(&debug_message, L"debug_message.exe");
26106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_PROCESS,
26206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                           sandbox::TargetPolicy::PROCESS_MIN_EXEC,
26306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                           debug_message.c_str());
26406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (result != sandbox::SBOX_ALL_OK)
26506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
26606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#endif  // NDEBUG
26706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
26806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return true;
26906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
27006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
27106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Creates a sandbox without any restriction.
27206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochbool ApplyPolicyForTrustedPlugin(sandbox::TargetPolicy* policy) {
27306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  policy->SetJobLevel(sandbox::JOB_UNPROTECTED, 0);
27406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  policy->SetTokenLevel(sandbox::USER_UNPROTECTED, sandbox::USER_UNPROTECTED);
27506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return true;
27606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
27706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
27806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Creates a sandbox with the plugin running in a restricted environment.
27906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Only the "Users" and "Everyone" groups are enabled in the token. The User SID
28006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// is disabled.
28106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochbool ApplyPolicyForUntrustedPlugin(sandbox::TargetPolicy* policy) {
28206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  policy->SetJobLevel(sandbox::JOB_UNPROTECTED, 0);
28306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
28406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED;
285731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (base::win::GetVersion() > base::win::VERSION_XP) {
28606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    // On 2003/Vista the initial token has to be restricted if the main token
28706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    // is restricted.
28806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS;
28906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
29006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  policy->SetTokenLevel(initial_token, sandbox::USER_LIMITED);
29106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
29206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
29306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!AddDirectory(base::DIR_TEMP, NULL, true,
29406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                    sandbox::TargetPolicy::FILES_ALLOW_ANY, policy))
29506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
29606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
29706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!AddDirectory(base::DIR_IE_INTERNET_CACHE, NULL, true,
29806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                    sandbox::TargetPolicy::FILES_ALLOW_ANY, policy))
29906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
30006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
30106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!AddDirectory(base::DIR_APP_DATA, NULL, true,
30206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                    sandbox::TargetPolicy::FILES_ALLOW_READONLY,
30306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                    policy))
30406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
30506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
30606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!AddDirectory(base::DIR_PROFILE, NULL, false,  /*not recursive*/
30706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                    sandbox::TargetPolicy::FILES_ALLOW_READONLY,
30806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                    policy))
30906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
31006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
31106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!AddDirectory(base::DIR_APP_DATA, L"Adobe", true,
31206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                    sandbox::TargetPolicy::FILES_ALLOW_ANY,
31306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                    policy))
31406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
31506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
31606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!AddDirectory(base::DIR_APP_DATA, L"Macromedia", true,
31706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                    sandbox::TargetPolicy::FILES_ALLOW_ANY,
31806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                    policy))
31906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
32006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
32106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!AddDirectory(base::DIR_LOCAL_APP_DATA, NULL, true,
32206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                    sandbox::TargetPolicy::FILES_ALLOW_READONLY,
32306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                    policy))
32406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
32506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
32606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!AddKeyAndSubkeys(L"HKEY_CURRENT_USER\\SOFTWARE\\ADOBE",
32706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                        sandbox::TargetPolicy::REG_ALLOW_ANY,
32806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                        policy))
32906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
33006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
33106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!AddKeyAndSubkeys(L"HKEY_CURRENT_USER\\SOFTWARE\\MACROMEDIA",
33206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                        sandbox::TargetPolicy::REG_ALLOW_ANY,
33306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                        policy))
33406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
33506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
336731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
33706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    if (!AddKeyAndSubkeys(L"HKEY_CURRENT_USER\\SOFTWARE\\AppDataLow",
33806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                          sandbox::TargetPolicy::REG_ALLOW_ANY,
33906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                          policy))
34006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      return false;
34106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
34206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    if (!AddDirectory(base::DIR_LOCAL_APP_DATA_LOW, NULL, true,
34306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                      sandbox::TargetPolicy::FILES_ALLOW_ANY,
34406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                      policy))
34506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      return false;
34606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
34706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    // DIR_APP_DATA is AppData\Roaming, but Adobe needs to do a directory
34806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    // listing in AppData directly, so we add a non-recursive policy for
34906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    // AppData itself.
35006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    if (!AddDirectory(base::DIR_APP_DATA, L"..", false,
35106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                      sandbox::TargetPolicy::FILES_ALLOW_READONLY,
35206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                      policy))
35306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      return false;
35406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
35506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
35606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return true;
35706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
35806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Launches the privileged flash broker, used when flash is sandboxed.
3603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// The broker is the same flash dll, except that it uses a different
3613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// entrypoint (BrokerMain) and it is hosted in windows' generic surrogate
3623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// process rundll32. After launching the broker we need to pass to
3633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// the flash plugin the process id of the broker via the command line
3643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// using --flash-broker=pid.
3653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// More info about rundll32 at http://support.microsoft.com/kb/164787.
3663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool LoadFlashBroker(const FilePath& plugin_path, CommandLine* cmd_line) {
3673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  FilePath rundll;
3683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!PathService::Get(base::DIR_SYSTEM, &rundll))
3693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return false;
3703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  rundll = rundll.AppendASCII("rundll32.exe");
3713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Rundll32 cannot handle paths with spaces, so we use the short path.
3723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  wchar_t short_path[MAX_PATH];
3733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (0 == ::GetShortPathNameW(plugin_path.value().c_str(),
3743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               short_path, arraysize(short_path)))
3753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return false;
37672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Here is the kicker, if the user has disabled 8.3 (short path) support
37772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // on the volume GetShortPathNameW does not fail but simply returns the
37872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // input path. In this case if the path had any spaces then rundll32 will
37972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // incorrectly interpret its parameters. So we quote the path, even though
38072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // the kb/164787 says you should not.
3813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::wstring cmd_final =
38272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      base::StringPrintf(L"%ls \"%ls\",BrokerMain browser=chrome",
3833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         rundll.value().c_str(),
3843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         short_path);
3853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  base::ProcessHandle process;
3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!base::LaunchApp(cmd_final, false, true, &process))
3873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return false;
3883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  cmd_line->AppendSwitchASCII("flash-broker",
3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                              base::Int64ToString(::GetProcessId(process)));
3914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
3924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // The flash broker, unders some circumstances can linger beyond the lifetime
3934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // of the flash player, so we put it in a job object, when the browser
3944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // terminates the job object is destroyed (by the OS) and the flash broker
3954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // is terminated.
3964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  HANDLE job = ::CreateJobObjectW(NULL, NULL);
3974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_limits = {0};
3984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  job_limits.BasicLimitInformation.LimitFlags =
3994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
4004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (::SetInformationJobObject(job, JobObjectExtendedLimitInformation,
4014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                                &job_limits, sizeof(job_limits))) {
4024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    ::AssignProcessToJobObject(job, process);
4034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // Yes, we are leaking the object here. Read comment above.
4044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  } else {
4054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    ::CloseHandle(job);
4064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return false;
4074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
4084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
4093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ::CloseHandle(process);
4103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return true;
4113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Creates a sandbox for the built-in flash plugin running in a restricted
41472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// environment. This policy is in continual flux as flash changes
41572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// capabilities. For more information see bug 50796.
4163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool ApplyPolicyForBuiltInFlashPlugin(sandbox::TargetPolicy* policy) {
4173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  policy->SetJobLevel(sandbox::JOB_UNPROTECTED, 0);
41872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Vista and Win7 get a weaker token but have low integrity.
41972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (base::win::GetVersion() > base::win::VERSION_XP) {
42072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    policy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
42172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          sandbox::USER_INTERACTIVE);
42272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
42372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else {
42472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    policy->SetTokenLevel(sandbox::USER_UNPROTECTED,
42572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          sandbox::USER_LIMITED);
4263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
42772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!AddKeyAndSubkeys(L"HKEY_LOCAL_MACHINE\\SOFTWARE",
42872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          sandbox::TargetPolicy::REG_ALLOW_READONLY,
42972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          policy))
43072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
43172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!AddKeyAndSubkeys(L"HKEY_LOCAL_MACHINE\\SYSTEM",
43272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          sandbox::TargetPolicy::REG_ALLOW_READONLY,
43372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          policy))
43472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
4353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
43672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!AddKeyAndSubkeys(L"HKEY_CURRENT_USER\\SOFTWARE",
43772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          sandbox::TargetPolicy::REG_ALLOW_READONLY,
43872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          policy))
43972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
44072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
4413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
44272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AddDllEvictionPolicy(policy);
4433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return true;
4443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Returns true of the plugin specified in |cmd_line| is the built-in
4474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// flash plugin and optionally returns its full path in |flash_path|
4484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochbool IsBuiltInFlash(const CommandLine* cmd_line, FilePath* flash_path) {
4494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  std::wstring plugin_dll = cmd_line->
4504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      GetSwitchValueNative(switches::kPluginPath);
4514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
4524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  FilePath builtin_flash;
4534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (!PathService::Get(chrome::FILE_FLASH_PLUGIN, &builtin_flash))
4544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return false;
4554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
4564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  FilePath plugin_path(plugin_dll);
4574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (plugin_path != builtin_flash)
4584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return false;
4594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
4604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (flash_path)
4614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    *flash_path = plugin_path;
4624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  return true;
4634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
4644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
4654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
46606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Adds the custom policy rules for a given plugin. |trusted_plugins| contains
46706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// the comma separate list of plugin dll names that should not be sandboxed.
4683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool AddPolicyForPlugin(CommandLine* cmd_line,
46906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                        sandbox::TargetPolicy* policy) {
47006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::wstring plugin_dll = cmd_line->
4713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      GetSwitchValueNative(switches::kPluginPath);
47206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::wstring trusted_plugins = CommandLine::ForCurrentProcess()->
4733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      GetSwitchValueNative(switches::kTrustedPlugins);
47406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Add the policy for the pipes.
47506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  sandbox::ResultCode result = sandbox::SBOX_ALL_OK;
47606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES,
47706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                           sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY,
47806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                           L"\\\\.\\pipe\\chrome.*");
47906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (result != sandbox::SBOX_ALL_OK) {
48006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    NOTREACHED();
48106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return false;
48206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
48306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
4843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The built-in flash gets a custom, more restricted sandbox.
4854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  FilePath flash_path;
4864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (IsBuiltInFlash(cmd_line, &flash_path)) {
4874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // Spawn the flash broker and apply sandbox policy.
4884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (!LoadFlashBroker(flash_path, cmd_line)) {
4894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      // Could not start the broker, use a very weak policy instead.
4904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      DLOG(WARNING) << "Failed to start flash broker";
4914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      return ApplyPolicyForTrustedPlugin(policy);
4923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
4934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return ApplyPolicyForBuiltInFlashPlugin(policy);
4943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
4953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
49606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  PluginPolicyCategory policy_category =
49706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      GetPolicyCategoryForPlugin(plugin_dll, trusted_plugins);
49806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
49906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  switch (policy_category) {
50006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    case PLUGIN_GROUP_TRUSTED:
50106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      return ApplyPolicyForTrustedPlugin(policy);
50206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    case PLUGIN_GROUP_UNTRUSTED:
50306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      return ApplyPolicyForUntrustedPlugin(policy);
50406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    default:
50506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      NOTREACHED();
50606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      break;
50706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
50806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
50906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return false;
51006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
51106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
512dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// For the GPU process we gotten as far as USER_LIMITED. The next level
513dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// which is USER_RESTRICTED breaks both the DirectX backend and the OpenGL
514dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// backend. Note that the GPU process is connected to the interactive
515dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// desktop.
516dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// TODO(cpu): Lock down the sandbox more if possible.
517dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// TODO(apatrick): Use D3D9Ex to render windowless.
518dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool AddPolicyForGPU(CommandLine*, sandbox::TargetPolicy* policy) {
519dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  policy->SetJobLevel(sandbox::JOB_UNPROTECTED, 0);
520dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
521dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (base::win::GetVersion() > base::win::VERSION_XP) {
522dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    policy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
523dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                          sandbox::USER_LIMITED);
524dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
525dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else {
526dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    policy->SetTokenLevel(sandbox::USER_UNPROTECTED,
527dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                          sandbox::USER_LIMITED);
528dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
529dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
530dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  AddDllEvictionPolicy(policy);
531dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return true;
532dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
533dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
53406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochvoid AddPolicyForRenderer(sandbox::TargetPolicy* policy,
53506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                          bool* on_sandbox_desktop) {
53606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0);
53706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
53806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED;
539731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (base::win::GetVersion() > base::win::VERSION_XP) {
54006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    // On 2003/Vista the initial token has to be restricted if the main
54106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    // token is restricted.
54206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS;
54306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
54406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
54506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  policy->SetTokenLevel(initial_token, sandbox::USER_LOCKDOWN);
54606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
54706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
54806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool use_winsta = !CommandLine::ForCurrentProcess()->HasSwitch(
54906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                        switches::kDisableAltWinstation);
55006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
55106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (sandbox::SBOX_ALL_OK ==  policy->SetAlternateDesktop(use_winsta)) {
55206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    *on_sandbox_desktop = true;
55306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  } else {
55406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    *on_sandbox_desktop = false;
55506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    DLOG(WARNING) << "Failed to apply desktop security to the renderer";
55606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
55706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
55806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  AddDllEvictionPolicy(policy);
55906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
56006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
56106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}  // namespace
56206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
56306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochnamespace sandbox {
56406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
56506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochvoid InitBrokerServices(sandbox::BrokerServices* broker_services) {
56606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // TODO(abarth): DCHECK(CalledOnValidThread());
56706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  //               See <http://b/1287166>.
56806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  CHECK(broker_services);
56906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  CHECK(!g_broker_services);
57006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  broker_services->Init();
57106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  g_broker_services = broker_services;
57206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
57306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
57406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdochbase::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line,
57506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                                           const FilePath& exposed_dir) {
57606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  base::ProcessHandle process = 0;
57706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
57806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  ChildProcessInfo::ProcessType type;
57906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::string type_str = cmd_line->GetSwitchValueASCII(switches::kProcessType);
58006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (type_str == switches::kRendererProcess) {
58106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    type = ChildProcessInfo::RENDER_PROCESS;
58206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  } else if (type_str == switches::kExtensionProcess) {
58306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    // Extensions are just renderers with another name.
58406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    type = ChildProcessInfo::RENDER_PROCESS;
58506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  } else if (type_str == switches::kPluginProcess) {
58606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    type = ChildProcessInfo::PLUGIN_PROCESS;
58706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  } else if (type_str == switches::kWorkerProcess) {
58806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    type = ChildProcessInfo::WORKER_PROCESS;
58906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  } else if (type_str == switches::kNaClLoaderProcess) {
59006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    type = ChildProcessInfo::NACL_LOADER_PROCESS;
59106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  } else if (type_str == switches::kUtilityProcess) {
59206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    type = ChildProcessInfo::UTILITY_PROCESS;
59306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  } else if (type_str == switches::kNaClBrokerProcess) {
59406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    type = ChildProcessInfo::NACL_BROKER_PROCESS;
59506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  } else if (type_str == switches::kGpuProcess) {
59606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    type = ChildProcessInfo::GPU_PROCESS;
5974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  } else if (type_str == switches::kPpapiPluginProcess) {
5984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    type = ChildProcessInfo::PPAPI_PLUGIN_PROCESS;
59906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  } else {
60006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    NOTREACHED();
60106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return 0;
60206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
60306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
6043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TRACE_EVENT_BEGIN("StartProcessWithAccess", 0, type_str);
6053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
6064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // To decide if the process is going to be sandboxed we have two cases.
607dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // First case: all process types except the nacl broker, and the plugin
608dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // process are sandboxed by default.
60906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool in_sandbox =
61006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      (type != ChildProcessInfo::NACL_BROKER_PROCESS) &&
6114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      (type != ChildProcessInfo::PLUGIN_PROCESS);
6124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
6134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Second case: If it is the plugin process then it depends on it being
6144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // the built-in flash, the user forcing plugins into sandbox or the
6154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // the user explicitly excluding flash from the sandbox.
6164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (!in_sandbox && (type == ChildProcessInfo::PLUGIN_PROCESS)) {
6174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      in_sandbox = browser_command_line.HasSwitch(switches::kSafePlugins) ||
6184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch          (IsBuiltInFlash(cmd_line, NULL) &&
6193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen           (base::win::GetVersion() > base::win::VERSION_XP) &&
62021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen           !browser_command_line.HasSwitch(switches::kDisableFlashSandbox));
6214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
6224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
623dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Third case: If it is the GPU process then it can be disabled by a
624dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // command line flag.
625dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if ((type == ChildProcessInfo::GPU_PROCESS) &&
626dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      (browser_command_line.HasSwitch(switches::kDisableGpuSandbox))) {
627dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    in_sandbox = false;
628dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    VLOG(1) << "GPU sandbox is disabled";
629dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
630dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
6314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (browser_command_line.HasSwitch(switches::kNoSandbox)) {
6324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // The user has explicity opted-out from all sandboxing.
6334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    in_sandbox = false;
6344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
6354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
63606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#if !defined (GOOGLE_CHROME_BUILD)
63706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (browser_command_line.HasSwitch(switches::kInProcessPlugins)) {
63806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    // In process plugins won't work if the sandbox is enabled.
63906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    in_sandbox = false;
64006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
64106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#endif
642ac1e49eb6695f711d72215fcdf9388548942a00dBen Murdoch  if (!browser_command_line.HasSwitch(switches::kDisable3DAPIs) &&
643ac1e49eb6695f711d72215fcdf9388548942a00dBen Murdoch      !browser_command_line.HasSwitch(switches::kDisableExperimentalWebGL) &&
64406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      browser_command_line.HasSwitch(switches::kInProcessWebGL)) {
64506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    // In process WebGL won't work if the sandbox is enabled.
64606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    in_sandbox = false;
64706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
64806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
64906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Propagate the Chrome Frame flag to sandboxed processes if present.
65006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (browser_command_line.HasSwitch(switches::kChromeFrame)) {
65106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    if (!cmd_line->HasSwitch(switches::kChromeFrame)) {
65206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      cmd_line->AppendSwitch(switches::kChromeFrame);
65306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    }
65406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
65506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
65606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool child_needs_help =
65706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      DebugFlags::ProcessDebugFlags(cmd_line, type, in_sandbox);
65806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
65906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Prefetch hints on windows:
66006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Using a different prefetch profile per process type will allow Windows
66106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // to create separate pretetch settings for browser, renderer etc.
662513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  cmd_line->AppendArg(base::StringPrintf("/prefetch:%d", type));
66306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
66406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!in_sandbox) {
66506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    base::LaunchApp(*cmd_line, false, false, &process);
66606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return process;
66706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
66806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
66906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  sandbox::ResultCode result;
67006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  PROCESS_INFORMATION target = {0};
67106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  sandbox::TargetPolicy* policy = g_broker_services->CreatePolicy();
67206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
67306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool on_sandbox_desktop = false;
67406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (type == ChildProcessInfo::PLUGIN_PROCESS) {
67506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    if (!AddPolicyForPlugin(cmd_line, policy))
67606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      return 0;
677dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else if (type == ChildProcessInfo::GPU_PROCESS) {
678dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (!AddPolicyForGPU(cmd_line, policy))
679dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      return 0;
68006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  } else {
68106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    AddPolicyForRenderer(policy, &on_sandbox_desktop);
68206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
68306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    if (type_str != switches::kRendererProcess) {
68406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      // Hack for Google Desktop crash. Trick GD into not injecting its DLL into
68506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      // this subprocess. See
68606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      // http://code.google.com/p/chromium/issues/detail?id=25580
6873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      cmd_line->AppendSwitchASCII("ignored", " --type=renderer ");
68806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    }
68906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
69006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
69106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!exposed_dir.empty()) {
69206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
69306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                             sandbox::TargetPolicy::FILES_ALLOW_ANY,
69472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                             exposed_dir.value().c_str());
69506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    if (result != sandbox::SBOX_ALL_OK)
69606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      return 0;
69706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
69806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    FilePath exposed_files = exposed_dir.AppendASCII("*");
69906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
70006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                             sandbox::TargetPolicy::FILES_ALLOW_ANY,
70172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                             exposed_files.value().c_str());
70206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    if (result != sandbox::SBOX_ALL_OK)
70306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      return 0;
70406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
70506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
70606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (!AddGenericPolicy(policy)) {
70706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    NOTREACHED();
70806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return 0;
70906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  }
71006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
7113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TRACE_EVENT_BEGIN("StartProcessWithAccess::LAUNCHPROCESS", 0, 0);
7123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
71306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  result = g_broker_services->SpawnTarget(
714731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      cmd_line->GetProgram().value().c_str(),
71506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      cmd_line->command_line_string().c_str(),
71606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      policy, &target);
71706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  policy->Release();
71806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
7193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TRACE_EVENT_END("StartProcessWithAccess::LAUNCHPROCESS", 0, 0);
7203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
72106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (sandbox::SBOX_ALL_OK != result)
72206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch    return 0;
72306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
72406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  ResumeThread(target.hThread);
72506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  CloseHandle(target.hThread);
72606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  process = target.hProcess;
72706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
72806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Help the process a little. It can't start the debugger by itself if
72906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // the process is in a sandbox.
73006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  if (child_needs_help)
731513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    base::debug::SpawnDebuggerOnProcess(target.dwProcessId);
73206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
73306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  return process;
73406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}
73506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
73606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch}  // namespace sandbox
737