Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: chrome/common/sandbox_mac.mm

Issue 4044002: Mac: block ability to stat arbitrary files in the Sandbox (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix review comments Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/common/common.sb ('k') | chrome/common/sandbox_mac_diraccess_unittest.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/common/sandbox_mac.h" 5 #include "chrome/common/sandbox_mac.h"
6 6
7 #include "base/debug_util.h" 7 #include "base/debug_util.h"
8 8
9 #import <Cocoa/Cocoa.h> 9 #import <Cocoa/Cocoa.h>
10 extern "C" { 10 extern "C" {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 CGImageSourceCreateWithData((CFDataRef)data, 235 CGImageSourceCreateWithData((CFDataRef)data,
236 NULL)); 236 NULL));
237 CGImageSourceGetStatus(img); 237 CGImageSourceGetStatus(img);
238 } 238 }
239 239
240 { // Native Client access to /dev/random. 240 { // Native Client access to /dev/random.
241 GetUrandomFD(); 241 GetUrandomFD();
242 } 242 }
243 } 243 }
244 244
245 // Build the Sandbox command necessary to allow access to a named directory
246 // indicated by |allowed_dir|.
247 // returns a string containing the sandbox profile commands necesary to allow
248 // access to that directory or nil if an error occured.
249 NSString* BuildAllowDirectoryAccessSandboxString(const FilePath& allowed_dir) {
250 // A whitelist is used to determine which directories can be statted
251 // This means that in the case of an /a/b/c/d/ directory, we may be able to
252 // stat the leaf directory, but not it's parent.
253 // The extension code in Chrome calls realpath() which fails if it can't call
254 // stat() on one of the parent directories in the path.
255 // The solution to this is to allow statting the parent directories themselves
256 // but not their contents. We need to add a separate rule for each parent
257 // directory.
258
259 // The sandbox only understands "real" paths. This resolving step is
260 // needed so the caller doesn't need to worry about things like /var
261 // being a link to /private/var (like in the paths CreateNewTempDirectory()
262 // returns).
263 FilePath allowed_dir_canonical(allowed_dir);
264 GetCanonicalSandboxPath(&allowed_dir_canonical);
265
266 // Collect a list of all parent directories.
267 FilePath last_path = allowed_dir_canonical;
268 std::vector<FilePath> subpaths;
269 for (FilePath path = allowed_dir_canonical.DirName();
270 path.value() != last_path.value();
271 path = path.DirName()) {
272 subpaths.push_back(path);
273 last_path = path;
274 }
275
276 // Iterate through all parents and allow stat() on them explicitly.
277 NSString* sandbox_command = @"(allow file-read-metadata ";
278 for (std::vector<FilePath>::reverse_iterator i = subpaths.rbegin();
279 i != subpaths.rend();
280 ++i) {
281 std::string subdir_escaped;
282 if (!QuotePlainString(i->value(), &subdir_escaped)) {
283 LOG(FATAL) << "String quoting failed " << i->value();
284 return nil;
285 }
286
287 NSString* subdir_escaped_ns =
288 base::SysUTF8ToNSString(subdir_escaped.c_str());
289 sandbox_command =
290 [sandbox_command stringByAppendingFormat:@"(literal \"%@\")",
291 subdir_escaped_ns];
292 }
293
294 // Finally append the leaf directory. Unlike it's parents (for which only
295 // stat() should be allowed), the leaf directory needs full access.
296 sandbox_command =
297 [sandbox_command
298 stringByAppendingString:@") (allow file-read* file-write* "];
299
300 std::string allowed_dir_escaped;
301 if (!QuoteStringForRegex(allowed_dir_canonical.value(),
302 &allowed_dir_escaped)) {
303 LOG(FATAL) << "Regex string quoting failed "
304 << allowed_dir_canonical.value();
305 return nil;
306 }
307
308 NSString* allowed_dir_canonical_ns =
309 base::SysUTF8ToNSString(allowed_dir_escaped.c_str());
310 sandbox_command =
311 [sandbox_command stringByAppendingFormat:@"(regex #\"%@\") )",
312 allowed_dir_canonical_ns];
313
314 return sandbox_command;
315 }
316
245 // Turns on the OS X sandbox for this process. 317 // Turns on the OS X sandbox for this process.
246 bool EnableSandbox(SandboxProcessType sandbox_type, 318 bool EnableSandbox(SandboxProcessType sandbox_type,
247 const FilePath& allowed_dir) { 319 const FilePath& allowed_dir) {
248 // Sanity - currently only SANDBOX_TYPE_UTILITY supports a directory being 320 // Sanity - currently only SANDBOX_TYPE_UTILITY supports a directory being
249 // passed in. 321 // passed in.
250 if (sandbox_type != SANDBOX_TYPE_UTILITY) { 322 if (sandbox_type != SANDBOX_TYPE_UTILITY) {
251 DCHECK(allowed_dir.empty()) 323 DCHECK(allowed_dir.empty())
252 << "Only SANDBOX_TYPE_UTILITY allows a custom directory parameter."; 324 << "Only SANDBOX_TYPE_UTILITY allows a custom directory parameter.";
253 } 325 }
254 // We use a custom sandbox definition file to lock things down as 326 // We use a custom sandbox definition file to lock things down as
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 sandbox_data = [sandbox_data 406 sandbox_data = [sandbox_data
335 stringByReplacingOccurrencesOfString:@"DISABLE_SANDBOX_DENIAL_LOGGING" 407 stringByReplacingOccurrencesOfString:@"DISABLE_SANDBOX_DENIAL_LOGGING"
336 withString:@"(with no-log)"]; 408 withString:@"(with no-log)"];
337 } else { 409 } else {
338 sandbox_data = [sandbox_data 410 sandbox_data = [sandbox_data
339 stringByReplacingOccurrencesOfString:@"DISABLE_SANDBOX_DENIAL_LOGGING" 411 stringByReplacingOccurrencesOfString:@"DISABLE_SANDBOX_DENIAL_LOGGING"
340 withString:@""]; 412 withString:@""];
341 } 413 }
342 414
343 if (!allowed_dir.empty()) { 415 if (!allowed_dir.empty()) {
344 // The sandbox only understands "real" paths. This resolving step is 416 NSString* allowed_dir_sandbox_command =
345 // needed so the caller doesn't need to worry about things like /var 417 BuildAllowDirectoryAccessSandboxString(allowed_dir);
346 // being a link to /private/var (like in the paths CreateNewTempDirectory()
347 // returns).
348 FilePath allowed_dir_canonical(allowed_dir);
349 GetCanonicalSandboxPath(&allowed_dir_canonical);
350 418
351 std::string allowed_dir_escaped; 419 if (allowed_dir_sandbox_command) { // May be nil if function fails.
352 if (!QuoteStringForRegex(allowed_dir_canonical.value(), 420 sandbox_data = [sandbox_data
353 &allowed_dir_escaped)) { 421 stringByReplacingOccurrencesOfString:@";ENABLE_DIRECTORY_ACCESS"
354 LOG(FATAL) << "Regex string quoting failed " << allowed_dir.value(); 422 withString:allowed_dir_sandbox_command];
355 return false;
356 } 423 }
357 NSString* allowed_dir_escaped_ns = base::SysUTF8ToNSString(
358 allowed_dir_escaped.c_str());
359 sandbox_data = [sandbox_data
360 stringByReplacingOccurrencesOfString:@";ENABLE_DIRECTORY_ACCESS"
361 withString:@""];
362 sandbox_data = [sandbox_data
363 stringByReplacingOccurrencesOfString:@"DIR_TO_ALLOW_ACCESS"
364 withString:allowed_dir_escaped_ns];
365
366 } 424 }
367 425
368 if (snow_leopard_or_higher) { 426 if (snow_leopard_or_higher) {
369 // 10.6-only Sandbox rules. 427 // 10.6-only Sandbox rules.
370 sandbox_data = [sandbox_data 428 sandbox_data = [sandbox_data
371 stringByReplacingOccurrencesOfString:@";10.6_ONLY" 429 stringByReplacingOccurrencesOfString:@";10.6_ONLY"
372 withString:@""]; 430 withString:@""];
373 // Splice the path of the user's home directory into the sandbox profile 431 // Splice the path of the user's home directory into the sandbox profile
374 // (see renderer.sb for details). 432 // (see renderer.sb for details).
375 // This code is in the 10.6-only block because the sandbox syntax we use 433 // This code is in the 10.6-only block because the sandbox syntax we use
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 if (HANDLE_EINTR(fcntl(fd, F_GETPATH, canonical_path)) != 0) { 479 if (HANDLE_EINTR(fcntl(fd, F_GETPATH, canonical_path)) != 0) {
422 PLOG(FATAL) << "GetCanonicalSandboxPath() failed for: " 480 PLOG(FATAL) << "GetCanonicalSandboxPath() failed for: "
423 << path->value(); 481 << path->value();
424 return; 482 return;
425 } 483 }
426 484
427 *path = FilePath(canonical_path); 485 *path = FilePath(canonical_path);
428 } 486 }
429 487
430 } // namespace sandbox 488 } // namespace sandbox
OLDNEW
« no previous file with comments | « chrome/common/common.sb ('k') | chrome/common/sandbox_mac_diraccess_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698