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