blob: 5e0e999c327b0413856b788fa9a74b3e8d644a00 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/browser/sandbox_policy.h"
6
7#include "base/file_util.h"
8#include "base/logging.h"
9#include "base/path_service.h"
10#include "base/registry.h"
11#include "base/string_util.h"
12#include "base/win_util.h"
13#include "chrome/common/chrome_constants.h"
14#include "chrome/common/chrome_paths.h"
15#include "chrome/common/ipc_logging.h"
16#include "chrome/common/win_util.h"
17#include "webkit/glue/plugins/plugin_list.h"
18
[email protected]49a608d2008-11-05 18:53:4519namespace {
20
21// The DLLs listed here are known (or under strong suspicion) of causing crashes
22// when they are loaded in the renderer.
23const wchar_t* const kTroublesomeDlls[] = {
24 L"adialhk.dll", // Kaspersky Internet Security.
25 L"acpiz.dll", // Unknown.
26 L"avgrsstx.dll", // AVG 8.
27 L"btkeyind.dll", // Widcomm Bluetooth.
28 L"cmcsyshk.dll", // CMC Internet Security.
29 L"dockshellhook.dll", // Stardock Objectdock.
30 L"GoogleDesktopNetwork3.DLL", // Google Desktop Search v5.
31 L"fwhook.dll", // PC Tools Firewall Plus.
32 L"hookprocesscreation.dll", // Blumentals Program protector.
33 L"hookterminateapis.dll", // Blumentals and Cyberprinter.
34 L"hookprintapis.dll", // Cyberprinter.
35 L"imon.dll", // NOD32 Antivirus.
36 L"ioloHL.dll", // Iolo (System Mechanic).
37 L"kloehk.dll", // Kaspersky Internet Security.
38 L"lawenforcer.dll", // Spyware-Browser AntiSpyware (Spybro).
39 L"libdivx.dll", // DivX.
40 L"lvprcinj01.dll", // Logitech QuickCam.
41 L"madchook.dll", // Madshi (generic hooking library).
42 L"mdnsnsp.dll", // Bonjour.
43 L"moonsysh.dll", // Moon Secure Antivirus.
44 L"npdivx32.dll", // DivX.
45 L"npggNT.des", // GameGuard 2008.
46 L"npggNT.dll", // GameGuard (older).
47 L"oawatch.dll", // Online Armor.
48 L"pavhook.dll", // Panda Internet Security.
49 L"pavshook.dll", // Panda Antivirus.
50 L"pctavhook.dll", // PC Tools Antivirus.
51 L"prntrack.dll", // Pharos Systems.
52 L"radhslib.dll", // Radiant Naomi Internet Filter.
53 L"radprlib.dll", // Radiant Naomi Internet Filter.
54 L"rlhook.dll", // Trustware Bufferzone.
55 L"r3hook.dll", // Kaspersky Internet Security.
56 L"sahook.dll", // McAfee Site Advisor.
57 L"sbrige.dll", // Unknown.
58 L"sc2hook.dll", // Supercopier 2.
59 L"sguard.dll", // Iolo (System Guard).
60 L"smumhook.dll", // Spyware Doctor version 5 and above.
61 L"ssldivx.dll", // DivX.
62 L"syncor11.dll", // SynthCore Midi interface.
63 L"systools.dll", // Panda Antivirus.
64 L"tfwah.dll", // Threatfire (PC tools).
65 L"wblind.dll", // Stardock Object desktop.
66 L"wbhelp.dll", // Stardock Object desktop.
67 L"winstylerthemehelper.dll" // Tuneup utilities 2006.
68};
69
70} // namespace
71
initial.commit09911bf2008-07-26 23:55:2972PluginPolicyCategory GetPolicyCategoryForPlugin(
[email protected]690a99c2009-01-06 16:48:4573 const FilePath& dll,
initial.commit09911bf2008-07-26 23:55:2974 const std::wstring& clsid,
75 const std::wstring& list) {
[email protected]690a99c2009-01-06 16:48:4576 std::wstring filename = dll.BaseName().value();
initial.commit09911bf2008-07-26 23:55:2977 std::wstring plugin_dll = StringToLowerASCII(filename);
78 std::wstring trusted_plugins = StringToLowerASCII(list);
79 std::wstring activex_clsid = StringToLowerASCII(clsid);
80
81 size_t pos = 0;
82 size_t end_item = 0;
[email protected]49a608d2008-11-05 18:53:4583 while (end_item != std::wstring::npos) {
initial.commit09911bf2008-07-26 23:55:2984 end_item = list.find(L",", pos);
85
86 size_t size_item = (end_item == std::wstring::npos) ? end_item :
87 end_item - pos;
88 std::wstring item = list.substr(pos, size_item);
89 if (!item.empty()) {
90 if (item == activex_clsid || item == plugin_dll)
91 return PLUGIN_GROUP_TRUSTED;
92 }
93
94 pos = end_item + 1;
95 }
96
97 return PLUGIN_GROUP_UNTRUSTED;
98}
99
100// Adds the policy rules for the path and path\* with the semantic |access|.
101// We need to add the wildcard rules to also apply the rule to the subfiles
102// and subfolders.
103bool AddDirectoryAndChildren(int path, const wchar_t* sub_dir,
104 sandbox::TargetPolicy::Semantics access,
105 sandbox::TargetPolicy* policy) {
106 std::wstring directory;
107 if (!PathService::Get(path, &directory))
108 return false;
109
110 if (sub_dir)
111 file_util::AppendToPath(&directory, sub_dir);
112
113 sandbox::ResultCode result;
114 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, access,
115 directory.c_str());
116 if (result != sandbox::SBOX_ALL_OK)
117 return false;
118
119 file_util::AppendToPath(&directory, L"*");
120 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, access,
121 directory.c_str());
122 if (result != sandbox::SBOX_ALL_OK)
123 return false;
124
125 return true;
126}
127
128// Adds the policy rules for the path and path\* with the semantic |access|.
129// We need to add the wildcard rules to also apply the rule to the subkeys.
130bool AddKeyAndSubkeys(std::wstring key,
131 sandbox::TargetPolicy::Semantics access,
132 sandbox::TargetPolicy* policy) {
133 sandbox::ResultCode result;
134 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_REGISTRY, access,
135 key.c_str());
136 if (result != sandbox::SBOX_ALL_OK)
137 return false;
138
139 key += L"\\*";
140 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_REGISTRY, access,
141 key.c_str());
142 if (result != sandbox::SBOX_ALL_OK)
143 return false;
144
145 return true;
146}
147
[email protected]49a608d2008-11-05 18:53:45148// Eviction of injected DLLs is done by the sandbox so that the injected module
149// does not get a chance to execute any code.
[email protected]0f8a6b42008-09-22 17:11:04150bool AddDllEvictionPolicy(sandbox::TargetPolicy* policy) {
[email protected]49a608d2008-11-05 18:53:45151 for (int ix = 0; ix != arraysize(kTroublesomeDlls); ++ix) {
[email protected]0f8a6b42008-09-22 17:11:04152 // To minimize the list we only add an unload policy if the dll is also
153 // loaded in this process. All the injected dlls of interest do this.
[email protected]49a608d2008-11-05 18:53:45154 if (::GetModuleHandleW(kTroublesomeDlls[ix])) {
155 LOG(WARNING) << "dll to unload found: " << kTroublesomeDlls[ix];
156 if (sandbox::SBOX_ALL_OK != policy->AddDllToUnload(kTroublesomeDlls[ix]))
[email protected]0f8a6b42008-09-22 17:11:04157 return false;
158 }
159 }
160
161 return true;
162}
163
[email protected]8ee8189e2008-10-08 19:35:21164bool AddPolicyForGearsInRenderer(sandbox::TargetPolicy* policy) {
165 sandbox::ResultCode result;
166
167 // TODO(mpcomplete): need to restrict access to database files only. This
168 // is just temporary for debugging purposes.
169 std::wstring plugin_data;
170 if (!PathService::Get(chrome::DIR_USER_DATA, &plugin_data))
171 return false;
172 if (!win_util::ConvertToLongPath(plugin_data, &plugin_data))
173 return false;
174
175 file_util::AppendToPath(&plugin_data, L"*");
176 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
177 sandbox::TargetPolicy::FILES_ALLOW_ANY,
178 plugin_data.c_str());
179 if (result != sandbox::SBOX_ALL_OK)
180 return false;
181
182 std::wstring temppath;
183 if (!file_util::GetTempDir(&temppath))
184 return false;
185 file_util::AppendToPath(&temppath, L"*");
186 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
187 sandbox::TargetPolicy::FILES_ALLOW_ANY,
188 temppath.c_str());
189 if (result != sandbox::SBOX_ALL_OK)
190 return false;
191
192 return true;
193}
194
initial.commit09911bf2008-07-26 23:55:29195bool AddGenericPolicy(sandbox::TargetPolicy* policy) {
196 sandbox::ResultCode result;
197
198 // Add the policy for the pipes
199 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
200 sandbox::TargetPolicy::FILES_ALLOW_ANY,
201 L"\\??\\pipe\\chrome.*");
202 if (result != sandbox::SBOX_ALL_OK)
203 return false;
204
205#ifdef IPC_MESSAGE_LOG_ENABLED
206 // Add the policy for the IPC logging events.
207 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_SYNC,
208 sandbox::TargetPolicy::EVENTS_ALLOW_ANY,
209 IPC::Logging::GetEventName(true).c_str());
210 if (result != sandbox::SBOX_ALL_OK)
211 return false;
212
213 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_SYNC,
214 sandbox::TargetPolicy::EVENTS_ALLOW_ANY,
215 IPC::Logging::GetEventName(false).c_str());
216 if (result != sandbox::SBOX_ALL_OK)
217 return false;
218#endif
219
220 // Add the policy for debug message only in debug
221#ifndef NDEBUG
222 std::wstring debug_message;
223 if (!PathService::Get(chrome::DIR_APP, &debug_message))
224 return false;
225 if (!win_util::ConvertToLongPath(debug_message, &debug_message))
226 return false;
227 file_util::AppendToPath(&debug_message, L"debug_message.exe");
228 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_PROCESS,
229 sandbox::TargetPolicy::PROCESS_MIN_EXEC,
230 debug_message.c_str());
231 if (result != sandbox::SBOX_ALL_OK)
232 return false;
233#endif // NDEBUG
234
235 return true;
236}
237
238bool ApplyPolicyForTrustedPlugin(sandbox::TargetPolicy* policy) {
239 policy->SetJobLevel(sandbox::JOB_UNPROTECTED, 0);
240 policy->SetTokenLevel(sandbox::USER_UNPROTECTED, sandbox::USER_UNPROTECTED);
241 return true;
242}
243
244bool ApplyPolicyForUntrustedPlugin(sandbox::TargetPolicy* policy) {
245 policy->SetJobLevel(sandbox::JOB_UNPROTECTED, 0);
246
247 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED;
248 if (win_util::GetWinVersion() > win_util::WINVERSION_XP) {
249 // On 2003/Vista the initial token has to be restricted if the main token
250 // is restricted.
251 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS;
252 }
253 policy->SetTokenLevel(initial_token, sandbox::USER_LIMITED);
254 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
255
256 if (!AddDirectoryAndChildren(base::DIR_TEMP, NULL,
257 sandbox::TargetPolicy::FILES_ALLOW_ANY, policy))
258 return false;
259
260 if (!AddDirectoryAndChildren(base::DIR_IE_INTERNET_CACHE, NULL,
261 sandbox::TargetPolicy::FILES_ALLOW_ANY, policy))
262 return false;
263
264
265 if (!AddDirectoryAndChildren(base::DIR_APP_DATA, NULL,
266 sandbox::TargetPolicy::FILES_ALLOW_READONLY,
267 policy))
268 return false;
269
270 if (!AddDirectoryAndChildren(base::DIR_APP_DATA, L"Macromedia",
271 sandbox::TargetPolicy::FILES_ALLOW_ANY,
272 policy))
273 return false;
274
275 if (!AddDirectoryAndChildren(base::DIR_LOCAL_APP_DATA, NULL,
276 sandbox::TargetPolicy::FILES_ALLOW_READONLY,
277 policy))
278 return false;
279
280 if (!AddKeyAndSubkeys(L"HKEY_CURRENT_USER\\SOFTWARE\\MACROMEDIA",
281 sandbox::TargetPolicy::REG_ALLOW_ANY,
282 policy))
283 return false;
284
285 if (win_util::GetWinVersion() == win_util::WINVERSION_VISTA) {
286 if (!AddKeyAndSubkeys(L"HKEY_CURRENT_USER\\SOFTWARE\\AppDataLow",
287 sandbox::TargetPolicy::REG_ALLOW_ANY,
288 policy))
289 return false;
290
291 if (!AddDirectoryAndChildren(base::DIR_LOCAL_APP_DATA_LOW, NULL,
292 sandbox::TargetPolicy::FILES_ALLOW_ANY,
293 policy))
294 return false;
295 }
296
297 return true;
298}
299
[email protected]690a99c2009-01-06 16:48:45300bool AddPolicyForPlugin(const FilePath &plugin_dll,
initial.commit09911bf2008-07-26 23:55:29301 const std::string &activex_clsid,
302 const std::wstring &trusted_plugins,
303 sandbox::TargetPolicy* policy) {
304 // Add the policy for the pipes.
305 sandbox::ResultCode result = sandbox::SBOX_ALL_OK;
306 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES,
307 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY,
308 L"\\\\.\\pipe\\chrome.*");
309 if (result != sandbox::SBOX_ALL_OK)
310 return false;
311
312 std::wstring clsid = UTF8ToWide(activex_clsid);
313
314 PluginPolicyCategory policy_category =
315 GetPolicyCategoryForPlugin(plugin_dll, clsid, trusted_plugins);
316
317 switch (policy_category) {
318 case PLUGIN_GROUP_TRUSTED:
319 return ApplyPolicyForTrustedPlugin(policy);
320 case PLUGIN_GROUP_UNTRUSTED:
321 return ApplyPolicyForUntrustedPlugin(policy);
322 default:
323 NOTREACHED();
324 break;
325 }
326
327 return false;
license.botbf09a502008-08-24 00:55:55328}