OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 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/common/sandbox_policy.h" | 5 #include "content/common/sandbox_policy.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/debug/debugger.h" | 10 #include "base/debug/debugger.h" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 L"pavshookwow.dll", // Panda Antivirus. | 62 L"pavshookwow.dll", // Panda Antivirus. |
63 L"pctavhook.dll", // PC Tools Antivirus. | 63 L"pctavhook.dll", // PC Tools Antivirus. |
64 L"pctgmhk.dll", // PC Tools Spyware Doctor. | 64 L"pctgmhk.dll", // PC Tools Spyware Doctor. |
65 L"prntrack.dll", // Pharos Systems. | 65 L"prntrack.dll", // Pharos Systems. |
66 L"radhslib.dll", // Radiant Naomi Internet Filter. | 66 L"radhslib.dll", // Radiant Naomi Internet Filter. |
67 L"radprlib.dll", // Radiant Naomi Internet Filter. | 67 L"radprlib.dll", // Radiant Naomi Internet Filter. |
68 L"rapportnikko.dll", // Trustware Rapport. | 68 L"rapportnikko.dll", // Trustware Rapport. |
69 L"rlhook.dll", // Trustware Bufferzone. | 69 L"rlhook.dll", // Trustware Bufferzone. |
70 L"rooksdol.dll", // Trustware Rapport. | 70 L"rooksdol.dll", // Trustware Rapport. |
71 L"rpchromebrowserrecordhelper.dll", // RealPlayer. | 71 L"rpchromebrowserrecordhelper.dll", // RealPlayer. |
72 L"rpmainbrowserrecordplugin.dll", // RealPlayer. | |
73 L"r3hook.dll", // Kaspersky Internet Security. | 72 L"r3hook.dll", // Kaspersky Internet Security. |
74 L"sahook.dll", // McAfee Site Advisor. | 73 L"sahook.dll", // McAfee Site Advisor. |
75 L"sbrige.dll", // Unknown. | 74 L"sbrige.dll", // Unknown. |
76 L"sc2hook.dll", // Supercopier 2. | 75 L"sc2hook.dll", // Supercopier 2. |
77 L"sguard.dll", // Iolo (System Guard). | 76 L"sguard.dll", // Iolo (System Guard). |
78 L"smum32.dll", // Spyware Doctor version 6. | 77 L"smum32.dll", // Spyware Doctor version 6. |
79 L"smumhook.dll", // Spyware Doctor version 5. | 78 L"smumhook.dll", // Spyware Doctor version 5. |
80 L"ssldivx.dll", // DivX. | 79 L"ssldivx.dll", // DivX. |
81 L"syncor11.dll", // SynthCore Midi interface. | 80 L"syncor11.dll", // SynthCore Midi interface. |
82 L"systools.dll", // Panda Antivirus. | 81 L"systools.dll", // Panda Antivirus. |
83 L"tfwah.dll", // Threatfire (PC tools). | 82 L"tfwah.dll", // Threatfire (PC tools). |
84 L"ycwebcamerasource.ax", // Cyberlink Camera helper. | |
85 L"wblind.dll", // Stardock Object desktop. | 83 L"wblind.dll", // Stardock Object desktop. |
86 L"wbhelp.dll", // Stardock Object desktop. | 84 L"wbhelp.dll", // Stardock Object desktop. |
87 L"winstylerthemehelper.dll" // Tuneup utilities 2006. | 85 L"winstylerthemehelper.dll" // Tuneup utilities 2006. |
88 }; | 86 }; |
89 | 87 |
| 88 // The DLLs listed here are known (or under strong suspicion) of causing crashes |
| 89 // when they are loaded in the plugin process. |
| 90 const wchar_t* const kTroublesomePluginDlls[] = { |
| 91 L"rpmainbrowserrecordplugin.dll", // RealPlayer. |
| 92 L"ycwebcamerasource.ax" // Cyberlink Camera helper. |
| 93 }; |
| 94 |
90 // Adds the policy rules for the path and path\ with the semantic |access|. | 95 // Adds the policy rules for the path and path\ with the semantic |access|. |
91 // If |children| is set to true, we need to add the wildcard rules to also | 96 // If |children| is set to true, we need to add the wildcard rules to also |
92 // apply the rule to the subfiles and subfolders. | 97 // apply the rule to the subfiles and subfolders. |
93 bool AddDirectory(int path, const wchar_t* sub_dir, bool children, | 98 bool AddDirectory(int path, const wchar_t* sub_dir, bool children, |
94 sandbox::TargetPolicy::Semantics access, | 99 sandbox::TargetPolicy::Semantics access, |
95 sandbox::TargetPolicy* policy) { | 100 sandbox::TargetPolicy* policy) { |
96 FilePath directory; | 101 FilePath directory; |
97 if (!PathService::Get(path, &directory)) | 102 if (!PathService::Get(path, &directory)) |
98 return false; | 103 return false; |
99 | 104 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 // XP does not set the last error properly, so we bail out anyway. | 154 // XP does not set the last error properly, so we bail out anyway. |
150 return false; | 155 return false; |
151 } | 156 } |
152 if (!::GetLongPathName(path, path, arraysize(path))) | 157 if (!::GetLongPathName(path, path, arraysize(path))) |
153 return false; | 158 return false; |
154 FilePath fname(path); | 159 FilePath fname(path); |
155 return (fname.BaseName().value() == module_name); | 160 return (fname.BaseName().value() == module_name); |
156 } | 161 } |
157 | 162 |
158 // Adds a single dll by |module_name| into the |policy| blacklist. | 163 // Adds a single dll by |module_name| into the |policy| blacklist. |
159 // To minimize the list we only add an unload policy only if the dll is | 164 // If |check_in_browser| is true we only add an unload policy only if the dll |
160 // also loaded in this process. All the injected dlls of interest do this. | 165 // is also loaded in this process. |
161 void BlacklistAddOneDll(const wchar_t* module_name, | 166 void BlacklistAddOneDll(const wchar_t* module_name, |
| 167 bool check_in_browser, |
162 sandbox::TargetPolicy* policy) { | 168 sandbox::TargetPolicy* policy) { |
163 HMODULE module = ::GetModuleHandleW(module_name); | 169 HMODULE module = check_in_browser ? ::GetModuleHandleW(module_name) : NULL; |
164 if (!module) { | 170 if (!module) { |
165 // The module could have been loaded with a 8.3 short name. We use | 171 // The module could have been loaded with a 8.3 short name. We use |
166 // the most common case: 'thelongname.dll' becomes 'thelon~1.dll'. | 172 // the most common case: 'thelongname.dll' becomes 'thelon~1.dll'. |
167 std::wstring name(module_name); | 173 std::wstring name(module_name); |
168 size_t period = name.rfind(L'.'); | 174 size_t period = name.rfind(L'.'); |
169 DCHECK_NE(std::string::npos, period); | 175 DCHECK_NE(std::string::npos, period); |
170 DCHECK_LE(3U, (name.size() - period)); | 176 DCHECK_LE(3U, (name.size() - period)); |
171 if (period <= 8) | 177 if (period <= 8) |
172 return; | 178 return; |
173 std::wstring alt_name = name.substr(0, 6) + L"~1"; | 179 std::wstring alt_name = name.substr(0, 6) + L"~1"; |
174 alt_name += name.substr(period, name.size()); | 180 alt_name += name.substr(period, name.size()); |
175 module = ::GetModuleHandleW(alt_name.c_str()); | 181 if (check_in_browser) { |
176 if (!module) | 182 module = ::GetModuleHandleW(alt_name.c_str()); |
177 return; | 183 if (!module) |
178 // We found it, but because it only has 6 significant letters, we | 184 return; |
179 // want to make sure it is the right one. | 185 // We found it, but because it only has 6 significant letters, we |
180 if (!IsExpandedModuleName(module, module_name)) | 186 // want to make sure it is the right one. |
181 return; | 187 if (!IsExpandedModuleName(module, module_name)) |
| 188 return; |
| 189 } |
182 // Found a match. We add both forms to the policy. | 190 // Found a match. We add both forms to the policy. |
183 policy->AddDllToUnload(alt_name.c_str()); | 191 policy->AddDllToUnload(alt_name.c_str()); |
184 } | 192 } |
185 policy->AddDllToUnload(module_name); | 193 policy->AddDllToUnload(module_name); |
186 VLOG(1) << "dll to unload found: " << module_name; | 194 VLOG(1) << "dll to unload found: " << module_name; |
187 return; | 195 return; |
188 } | 196 } |
189 | 197 |
190 // Adds policy rules for unloaded the known dlls that cause chrome to crash. | 198 // Adds policy rules for unloaded the known dlls that cause chrome to crash. |
191 // Eviction of injected DLLs is done by the sandbox so that the injected module | 199 // Eviction of injected DLLs is done by the sandbox so that the injected module |
192 // does not get a chance to execute any code. | 200 // does not get a chance to execute any code. |
193 void AddDllEvictionPolicy(sandbox::TargetPolicy* policy) { | 201 void AddGenericDllEvictionPolicy(sandbox::TargetPolicy* policy) { |
194 for (int ix = 0; ix != arraysize(kTroublesomeDlls); ++ix) | 202 for (int ix = 0; ix != arraysize(kTroublesomeDlls); ++ix) |
195 BlacklistAddOneDll(kTroublesomeDlls[ix], policy); | 203 BlacklistAddOneDll(kTroublesomeDlls[ix], true, policy); |
| 204 } |
| 205 |
| 206 // Same as AddGenericDllEvictionPolicy but specifically for plugins. In this |
| 207 // case we add the blacklisted dlls even if they are not loaded in this process. |
| 208 void AddPluginDllEvictionPolicy(sandbox::TargetPolicy* policy) { |
| 209 for (int ix = 0; ix != arraysize(kTroublesomePluginDlls); ++ix) |
| 210 BlacklistAddOneDll(kTroublesomePluginDlls[ix], false, policy); |
196 } | 211 } |
197 | 212 |
198 // Returns the object path prepended with the current logon session. | 213 // Returns the object path prepended with the current logon session. |
199 string16 PrependWindowsSessionPath(const char16* object) { | 214 string16 PrependWindowsSessionPath(const char16* object) { |
200 // Cache this because it can't change after process creation. | 215 // Cache this because it can't change after process creation. |
201 uintptr_t s_session_id = 0; | 216 uintptr_t s_session_id = 0; |
202 if (s_session_id == 0) { | 217 if (s_session_id == 0) { |
203 HANDLE token; | 218 HANDLE token; |
204 DWORD session_id_length; | 219 DWORD session_id_length; |
205 DWORD session_id = 0; | 220 DWORD session_id = 0; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 if (cmd_line->GetSwitchValueASCII(switches::kUseGL) == | 295 if (cmd_line->GetSwitchValueASCII(switches::kUseGL) == |
281 gfx::kGLImplementationDesktopName) | 296 gfx::kGLImplementationDesktopName) |
282 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); | 297 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); |
283 else | 298 else |
284 policy->SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); | 299 policy->SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); |
285 } else { | 300 } else { |
286 policy->SetTokenLevel(sandbox::USER_UNPROTECTED, | 301 policy->SetTokenLevel(sandbox::USER_UNPROTECTED, |
287 sandbox::USER_LIMITED); | 302 sandbox::USER_LIMITED); |
288 } | 303 } |
289 | 304 |
290 AddDllEvictionPolicy(policy); | 305 AddGenericDllEvictionPolicy(policy); |
291 return true; | 306 return true; |
292 } | 307 } |
293 | 308 |
294 void AddPolicyForRenderer(sandbox::TargetPolicy* policy) { | 309 void AddPolicyForRenderer(sandbox::TargetPolicy* policy) { |
295 policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0); | 310 policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0); |
296 | 311 |
297 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED; | 312 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED; |
298 if (base::win::GetVersion() > base::win::VERSION_XP) { | 313 if (base::win::GetVersion() > base::win::VERSION_XP) { |
299 // On 2003/Vista the initial token has to be restricted if the main | 314 // On 2003/Vista the initial token has to be restricted if the main |
300 // token is restricted. | 315 // token is restricted. |
301 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS; | 316 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS; |
302 } | 317 } |
303 | 318 |
304 policy->SetTokenLevel(initial_token, sandbox::USER_LOCKDOWN); | 319 policy->SetTokenLevel(initial_token, sandbox::USER_LOCKDOWN); |
305 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); | 320 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW); |
306 | 321 |
307 bool use_winsta = !CommandLine::ForCurrentProcess()->HasSwitch( | 322 bool use_winsta = !CommandLine::ForCurrentProcess()->HasSwitch( |
308 switches::kDisableAltWinstation); | 323 switches::kDisableAltWinstation); |
309 | 324 |
310 if (sandbox::SBOX_ALL_OK != policy->SetAlternateDesktop(use_winsta)) { | 325 if (sandbox::SBOX_ALL_OK != policy->SetAlternateDesktop(use_winsta)) { |
311 DLOG(WARNING) << "Failed to apply desktop security to the renderer"; | 326 DLOG(WARNING) << "Failed to apply desktop security to the renderer"; |
312 } | 327 } |
313 | 328 |
314 AddDllEvictionPolicy(policy); | 329 AddGenericDllEvictionPolicy(policy); |
315 } | 330 } |
316 | 331 |
317 // The Pepper process as locked-down as a renderer execpt that it can | 332 // The Pepper process as locked-down as a renderer execpt that it can |
318 // create the server side of chrome pipes. | 333 // create the server side of chrome pipes. |
319 bool AddPolicyForPepperPlugin(sandbox::TargetPolicy* policy) { | 334 bool AddPolicyForPepperPlugin(sandbox::TargetPolicy* policy) { |
320 sandbox::ResultCode result; | 335 sandbox::ResultCode result; |
321 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, | 336 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES, |
322 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, | 337 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY, |
323 L"\\\\.\\pipe\\chrome.*"); | 338 L"\\\\.\\pipe\\chrome.*"); |
324 if (result != sandbox::SBOX_ALL_OK) { | 339 if (result != sandbox::SBOX_ALL_OK) { |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 in_sandbox = true; | 446 in_sandbox = true; |
432 } | 447 } |
433 | 448 |
434 if (!in_sandbox) { | 449 if (!in_sandbox) { |
435 policy->Release(); | 450 policy->Release(); |
436 base::LaunchProcess(*cmd_line, base::LaunchOptions(), &process); | 451 base::LaunchProcess(*cmd_line, base::LaunchOptions(), &process); |
437 return process; | 452 return process; |
438 } | 453 } |
439 | 454 |
440 if (type == ChildProcessInfo::PLUGIN_PROCESS) { | 455 if (type == ChildProcessInfo::PLUGIN_PROCESS) { |
441 AddDllEvictionPolicy(policy); | 456 AddGenericDllEvictionPolicy(policy); |
| 457 AddPluginDllEvictionPolicy(policy); |
442 } else if (type == ChildProcessInfo::GPU_PROCESS) { | 458 } else if (type == ChildProcessInfo::GPU_PROCESS) { |
443 if (!AddPolicyForGPU(cmd_line, policy)) | 459 if (!AddPolicyForGPU(cmd_line, policy)) |
444 return 0; | 460 return 0; |
445 } else if (type == ChildProcessInfo::PPAPI_PLUGIN_PROCESS) { | 461 } else if (type == ChildProcessInfo::PPAPI_PLUGIN_PROCESS) { |
446 if (!AddPolicyForPepperPlugin(policy)) | 462 if (!AddPolicyForPepperPlugin(policy)) |
447 return 0; | 463 return 0; |
448 } else { | 464 } else { |
449 AddPolicyForRenderer(policy); | 465 AddPolicyForRenderer(policy); |
450 // TODO(jschuh): Need get these restrictions applied to NaCl and Pepper. | 466 // TODO(jschuh): Need get these restrictions applied to NaCl and Pepper. |
451 // Just have to figure out what needs to be warmed up first. | 467 // Just have to figure out what needs to be warmed up first. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
501 | 517 |
502 // Help the process a little. It can't start the debugger by itself if | 518 // Help the process a little. It can't start the debugger by itself if |
503 // the process is in a sandbox. | 519 // the process is in a sandbox. |
504 if (child_needs_help) | 520 if (child_needs_help) |
505 base::debug::SpawnDebuggerOnProcess(target.dwProcessId); | 521 base::debug::SpawnDebuggerOnProcess(target.dwProcessId); |
506 | 522 |
507 return process; | 523 return process; |
508 } | 524 } |
509 | 525 |
510 } // namespace sandbox | 526 } // namespace sandbox |
OLD | NEW |