OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_mac.h" | 5 #include "content/common/sandbox_mac.h" |
6 | 6 |
7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
8 | 8 |
9 #include <CoreFoundation/CFTimeZone.h> | 9 #include <CoreFoundation/CFTimeZone.h> |
10 extern "C" { | 10 extern "C" { |
(...skipping 26 matching lines...) Expand all Loading... |
37 #include "content/grit/content_resources.h" | 37 #include "content/grit/content_resources.h" |
38 #include "content/public/common/content_client.h" | 38 #include "content/public/common/content_client.h" |
39 #include "content/public/common/content_switches.h" | 39 #include "content/public/common/content_switches.h" |
40 #include "third_party/icu/source/common/unicode/uchar.h" | 40 #include "third_party/icu/source/common/unicode/uchar.h" |
41 #include "ui/base/layout.h" | 41 #include "ui/base/layout.h" |
42 #include "ui/gl/gl_surface.h" | 42 #include "ui/gl/gl_surface.h" |
43 | 43 |
44 extern "C" { | 44 extern "C" { |
45 void CGSSetDenyWindowServerConnections(bool); | 45 void CGSSetDenyWindowServerConnections(bool); |
46 void CGSShutdownServerConnections(); | 46 void CGSShutdownServerConnections(); |
| 47 |
| 48 void* sandbox_create_params(); |
| 49 int sandbox_set_param(void* params, const char* key, const char* value); |
| 50 void* sandbox_compile_string(const char* profile_str, |
| 51 void* params, |
| 52 char** error); |
| 53 int sandbox_apply(void* profile); |
| 54 void sandbox_free_params(void* params); |
| 55 void sandbox_free_profile(void* profile); |
47 }; | 56 }; |
48 | 57 |
49 namespace content { | 58 namespace content { |
50 namespace { | 59 namespace { |
51 | 60 |
52 // Is the sandbox currently active. | 61 // Is the sandbox currently active. |
53 bool gSandboxIsActive = false; | 62 bool gSandboxIsActive = false; |
54 | 63 |
55 struct SandboxTypeToResourceIDMapping { | 64 struct SandboxTypeToResourceIDMapping { |
56 SandboxType sandbox_type; | 65 SandboxType sandbox_type; |
57 int sandbox_profile_resource_id; | 66 int sandbox_profile_resource_id; |
58 }; | 67 }; |
59 | 68 |
| 69 // This is the internal definition of the structure used by sandbox parameters |
| 70 // on OS X 10.6. |
| 71 struct SandboxParams { |
| 72 void* buf; |
| 73 size_t count; |
| 74 size_t size; |
| 75 }; |
| 76 |
60 // Mapping from sandbox process types to resource IDs containing the sandbox | 77 // Mapping from sandbox process types to resource IDs containing the sandbox |
61 // profile for all process types known to content. | 78 // profile for all process types known to content. |
62 SandboxTypeToResourceIDMapping kDefaultSandboxTypeToResourceIDMapping[] = { | 79 SandboxTypeToResourceIDMapping kDefaultSandboxTypeToResourceIDMapping[] = { |
63 { SANDBOX_TYPE_RENDERER, IDR_RENDERER_SANDBOX_PROFILE }, | 80 { SANDBOX_TYPE_RENDERER, IDR_RENDERER_SANDBOX_PROFILE }, |
64 { SANDBOX_TYPE_UTILITY, IDR_UTILITY_SANDBOX_PROFILE }, | 81 { SANDBOX_TYPE_UTILITY, IDR_UTILITY_SANDBOX_PROFILE }, |
65 { SANDBOX_TYPE_GPU, IDR_GPU_SANDBOX_PROFILE }, | 82 { SANDBOX_TYPE_GPU, IDR_GPU_SANDBOX_PROFILE }, |
66 { SANDBOX_TYPE_PPAPI, IDR_PPAPI_SANDBOX_PROFILE }, | 83 { SANDBOX_TYPE_PPAPI, IDR_PPAPI_SANDBOX_PROFILE }, |
67 }; | 84 }; |
68 | 85 |
69 static_assert(arraysize(kDefaultSandboxTypeToResourceIDMapping) == \ | 86 static_assert(arraysize(kDefaultSandboxTypeToResourceIDMapping) == \ |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 // in a central place. | 127 // in a central place. |
111 NOINLINE void FatalStringQuoteException(const std::string& str) { | 128 NOINLINE void FatalStringQuoteException(const std::string& str) { |
112 // Copy bad string to the stack so it's recorded in the crash dump. | 129 // Copy bad string to the stack so it's recorded in the crash dump. |
113 char bad_string[256] = {0}; | 130 char bad_string[256] = {0}; |
114 base::strlcpy(bad_string, str.c_str(), arraysize(bad_string)); | 131 base::strlcpy(bad_string, str.c_str(), arraysize(bad_string)); |
115 DLOG(FATAL) << "String quoting failed " << bad_string; | 132 DLOG(FATAL) << "String quoting failed " << bad_string; |
116 } | 133 } |
117 | 134 |
118 } // namespace | 135 } // namespace |
119 | 136 |
120 // static | 137 SandboxCompiler::SandboxCompiler(const std::string& profile_str) |
121 NSString* Sandbox::AllowMetadataForPath(const base::FilePath& allowed_path) { | 138 : params_map_(), profile_str_(profile_str) { |
122 // Collect a list of all parent directories. | 139 } |
123 base::FilePath last_path = allowed_path; | 140 |
124 std::vector<base::FilePath> subpaths; | 141 SandboxCompiler::~SandboxCompiler() { |
125 for (base::FilePath path = allowed_path; | 142 } |
126 path.value() != last_path.value(); | 143 |
127 path = path.DirName()) { | 144 bool SandboxCompiler::InsertBooleanParam(const std::string& key, bool value) { |
128 subpaths.push_back(path); | 145 return params_map_.insert(std::make_pair(key, value ? "TRUE" : "FALSE")) |
129 last_path = path; | 146 .second; |
| 147 } |
| 148 |
| 149 bool SandboxCompiler::InsertStringParam(const std::string& key, |
| 150 const std::string& value) { |
| 151 return params_map_.insert(std::make_pair(key, value)).second; |
| 152 } |
| 153 |
| 154 void SandboxCompiler::FreeSandboxResources(void* profile, |
| 155 void* params, |
| 156 char* error) { |
| 157 if (error) |
| 158 sandbox_free_error(error); |
| 159 if (params) |
| 160 sandbox_free_params(params); |
| 161 if (profile) |
| 162 sandbox_free_profile(profile); |
| 163 } |
| 164 |
| 165 bool SandboxCompiler::CompileAndApplyProfile(std::string* error) { |
| 166 char* error_internal = nullptr; |
| 167 void* profile = nullptr; |
| 168 void* params = nullptr; |
| 169 |
| 170 if (!params_map_.empty()) { |
| 171 if (base::mac::IsOSSnowLeopard()) { |
| 172 // This is a workaround for 10.6, see crbug.com/509114. |
| 173 // Check that there is no integer overflow. |
| 174 base::CheckedNumeric<size_t> checked_size = params_map_.size(); |
| 175 checked_size *= 2; |
| 176 if (!checked_size.IsValid()) |
| 177 return false; |
| 178 |
| 179 SandboxParams* internal_params = |
| 180 static_cast<SandboxParams*>(malloc(sizeof(SandboxParams))); |
| 181 internal_params->buf = calloc(checked_size.ValueOrDie(), sizeof(void*)); |
| 182 internal_params->count = 0; |
| 183 internal_params->size = checked_size.ValueOrDie(); |
| 184 params = internal_params; |
| 185 } else { |
| 186 params = sandbox_create_params(); |
| 187 if (!params) |
| 188 return false; |
| 189 } |
| 190 |
| 191 for (const auto& kv : params_map_) |
| 192 sandbox_set_param(params, kv.first.c_str(), kv.second.c_str()); |
130 } | 193 } |
131 | 194 |
132 // Iterate through all parents and allow stat() on them explicitly. | 195 profile = |
133 NSString* sandbox_command = @"(allow file-read-metadata "; | 196 sandbox_compile_string(profile_str_.c_str(), params, &error_internal); |
134 for (std::vector<base::FilePath>::reverse_iterator i = subpaths.rbegin(); | 197 if (!profile) { |
135 i != subpaths.rend(); | 198 error->assign(error_internal); |
136 ++i) { | 199 FreeSandboxResources(profile, params, error_internal); |
137 std::string subdir_escaped; | 200 return false; |
138 if (!QuotePlainString(i->value(), &subdir_escaped)) { | |
139 FatalStringQuoteException(i->value()); | |
140 return nil; | |
141 } | |
142 | |
143 NSString* subdir_escaped_ns = | |
144 base::SysUTF8ToNSString(subdir_escaped.c_str()); | |
145 sandbox_command = | |
146 [sandbox_command stringByAppendingFormat:@"(literal \"%@\")", | |
147 subdir_escaped_ns]; | |
148 } | 201 } |
149 | 202 |
150 return [sandbox_command stringByAppendingString:@")"]; | 203 int result = sandbox_apply(profile); |
| 204 FreeSandboxResources(profile, params, error_internal); |
| 205 return result == 0; |
151 } | 206 } |
152 | 207 |
153 // static | 208 // static |
154 bool Sandbox::QuotePlainString(const std::string& src_utf8, std::string* dst) { | 209 bool Sandbox::QuotePlainString(const std::string& src_utf8, std::string* dst) { |
155 dst->clear(); | 210 dst->clear(); |
156 | 211 |
157 const char* src = src_utf8.c_str(); | 212 const char* src = src_utf8.c_str(); |
158 int32_t length = src_utf8.length(); | 213 int32_t length = src_utf8.length(); |
159 int32_t position = 0; | 214 int32_t position = 0; |
160 while (position < length) { | 215 while (position < length) { |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 // Shutting down the connection requires connecting to WindowServer, | 398 // Shutting down the connection requires connecting to WindowServer, |
344 // so do this before actually engaging the sandbox. This is only done on | 399 // so do this before actually engaging the sandbox. This is only done on |
345 // 10.8 and higher because doing it on earlier OSes causes layout tests to | 400 // 10.8 and higher because doing it on earlier OSes causes layout tests to |
346 // fail <http://crbug.com/397642#c48>. This may cause two log messages to | 401 // fail <http://crbug.com/397642#c48>. This may cause two log messages to |
347 // be printed to the system logger on certain OS versions. | 402 // be printed to the system logger on certain OS versions. |
348 CGSSetDenyWindowServerConnections(true); | 403 CGSSetDenyWindowServerConnections(true); |
349 CGSShutdownServerConnections(); | 404 CGSShutdownServerConnections(); |
350 } | 405 } |
351 } | 406 } |
352 | 407 |
353 // static | |
354 NSString* Sandbox::BuildAllowDirectoryAccessSandboxString( | |
355 const base::FilePath& allowed_dir, | |
356 SandboxVariableSubstitions* substitutions) { | |
357 // A whitelist is used to determine which directories can be statted | |
358 // This means that in the case of an /a/b/c/d/ directory, we may be able to | |
359 // stat the leaf directory, but not its parent. | |
360 // The extension code in Chrome calls realpath() which fails if it can't call | |
361 // stat() on one of the parent directories in the path. | |
362 // The solution to this is to allow statting the parent directories themselves | |
363 // but not their contents. We need to add a separate rule for each parent | |
364 // directory. | |
365 | |
366 // The sandbox only understands "real" paths. This resolving step is | |
367 // needed so the caller doesn't need to worry about things like /var | |
368 // being a link to /private/var (like in the paths CreateNewTempDirectory() | |
369 // returns). | |
370 base::FilePath allowed_dir_canonical = GetCanonicalSandboxPath(allowed_dir); | |
371 | |
372 NSString* sandbox_command = AllowMetadataForPath(allowed_dir_canonical); | |
373 sandbox_command = [sandbox_command | |
374 substringToIndex:[sandbox_command length] - 1]; // strip trailing ')' | |
375 | |
376 // Finally append the leaf directory. Unlike its parents (for which only | |
377 // stat() should be allowed), the leaf directory needs full access. | |
378 (*substitutions)["ALLOWED_DIR"] = | |
379 SandboxSubstring(allowed_dir_canonical.value(), | |
380 SandboxSubstring::REGEX); | |
381 sandbox_command = | |
382 [sandbox_command | |
383 stringByAppendingString:@") (allow file-read* file-write*" | |
384 " (regex #\"@ALLOWED_DIR@\") )"]; | |
385 return sandbox_command; | |
386 } | |
387 | |
388 // Load the appropriate template for the given sandbox type. | 408 // Load the appropriate template for the given sandbox type. |
389 // Returns the template as an NSString or nil on error. | 409 // Returns the template as an NSString or nil on error. |
390 NSString* LoadSandboxTemplate(int sandbox_type) { | 410 NSString* LoadSandboxTemplate(int sandbox_type) { |
391 // We use a custom sandbox definition to lock things down as tightly as | 411 // We use a custom sandbox definition to lock things down as tightly as |
392 // possible. | 412 // possible. |
393 int sandbox_profile_resource_id = -1; | 413 int sandbox_profile_resource_id = -1; |
394 | 414 |
395 // Find resource id for sandbox profile to use for the specific sandbox type. | 415 // Find resource id for sandbox profile to use for the specific sandbox type. |
396 for (size_t i = 0; | 416 for (size_t i = 0; |
397 i < arraysize(kDefaultSandboxTypeToResourceIDMapping); | 417 i < arraysize(kDefaultSandboxTypeToResourceIDMapping); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 | 455 |
436 base::scoped_nsobject<NSString> sandbox_data( | 456 base::scoped_nsobject<NSString> sandbox_data( |
437 [[NSString alloc] initWithBytes:sandbox_definition.data() | 457 [[NSString alloc] initWithBytes:sandbox_definition.data() |
438 length:sandbox_definition.length() | 458 length:sandbox_definition.length() |
439 encoding:NSUTF8StringEncoding]); | 459 encoding:NSUTF8StringEncoding]); |
440 | 460 |
441 // Prefix sandbox_data with common_sandbox_prefix_data. | 461 // Prefix sandbox_data with common_sandbox_prefix_data. |
442 return [common_sandbox_prefix_data stringByAppendingString:sandbox_data]; | 462 return [common_sandbox_prefix_data stringByAppendingString:sandbox_data]; |
443 } | 463 } |
444 | 464 |
445 // static | |
446 bool Sandbox::PostProcessSandboxProfile( | |
447 NSString* sandbox_template, | |
448 NSArray* comments_to_remove, | |
449 SandboxVariableSubstitions& substitutions, | |
450 std::string *final_sandbox_profile_str) { | |
451 NSString* sandbox_data = [[sandbox_template copy] autorelease]; | |
452 | |
453 // Remove comments, e.g. ;10.7_OR_ABOVE . | |
454 for (NSString* to_remove in comments_to_remove) { | |
455 sandbox_data = [sandbox_data stringByReplacingOccurrencesOfString:to_remove | |
456 withString:@""]; | |
457 } | |
458 | |
459 // Split string on "@" characters. | |
460 std::vector<std::string> raw_sandbox_pieces = base::SplitString( | |
461 [sandbox_data UTF8String], "@", base::KEEP_WHITESPACE, | |
462 base::SPLIT_WANT_NONEMPTY); | |
463 if (raw_sandbox_pieces.empty()) { | |
464 DLOG(FATAL) << "Bad Sandbox profile, should contain at least one token (" | |
465 << [sandbox_data UTF8String] | |
466 << ")"; | |
467 return false; | |
468 } | |
469 | |
470 // Iterate over string pieces and substitute variables, escaping as necessary. | |
471 size_t output_string_length = 0; | |
472 std::vector<std::string> processed_sandbox_pieces(raw_sandbox_pieces.size()); | |
473 for (std::vector<std::string>::iterator it = raw_sandbox_pieces.begin(); | |
474 it != raw_sandbox_pieces.end(); | |
475 ++it) { | |
476 std::string new_piece; | |
477 SandboxVariableSubstitions::iterator replacement_it = | |
478 substitutions.find(*it); | |
479 if (replacement_it == substitutions.end()) { | |
480 new_piece = *it; | |
481 } else { | |
482 // Found something to substitute. | |
483 SandboxSubstring& replacement = replacement_it->second; | |
484 switch (replacement.type()) { | |
485 case SandboxSubstring::PLAIN: | |
486 new_piece = replacement.value(); | |
487 break; | |
488 | |
489 case SandboxSubstring::LITERAL: | |
490 if (!QuotePlainString(replacement.value(), &new_piece)) | |
491 FatalStringQuoteException(replacement.value()); | |
492 break; | |
493 | |
494 case SandboxSubstring::REGEX: | |
495 if (!QuoteStringForRegex(replacement.value(), &new_piece)) | |
496 FatalStringQuoteException(replacement.value()); | |
497 break; | |
498 } | |
499 } | |
500 output_string_length += new_piece.size(); | |
501 processed_sandbox_pieces.push_back(new_piece); | |
502 } | |
503 | |
504 // Build final output string. | |
505 final_sandbox_profile_str->reserve(output_string_length); | |
506 | |
507 for (std::vector<std::string>::iterator it = processed_sandbox_pieces.begin(); | |
508 it != processed_sandbox_pieces.end(); | |
509 ++it) { | |
510 final_sandbox_profile_str->append(*it); | |
511 } | |
512 return true; | |
513 } | |
514 | |
515 | |
516 // Turns on the OS X sandbox for this process. | 465 // Turns on the OS X sandbox for this process. |
517 | 466 |
518 // static | 467 // static |
519 bool Sandbox::EnableSandbox(int sandbox_type, | 468 bool Sandbox::EnableSandbox(int sandbox_type, |
520 const base::FilePath& allowed_dir) { | 469 const base::FilePath& allowed_dir) { |
521 // Sanity - currently only SANDBOX_TYPE_UTILITY supports a directory being | 470 // Sanity - currently only SANDBOX_TYPE_UTILITY supports a directory being |
522 // passed in. | 471 // passed in. |
523 if (sandbox_type < SANDBOX_TYPE_AFTER_LAST_TYPE && | 472 if (sandbox_type < SANDBOX_TYPE_AFTER_LAST_TYPE && |
524 sandbox_type != SANDBOX_TYPE_UTILITY) { | 473 sandbox_type != SANDBOX_TYPE_UTILITY) { |
525 DCHECK(allowed_dir.empty()) | 474 DCHECK(allowed_dir.empty()) |
526 << "Only SANDBOX_TYPE_UTILITY allows a custom directory parameter."; | 475 << "Only SANDBOX_TYPE_UTILITY allows a custom directory parameter."; |
527 } | 476 } |
528 | 477 |
529 NSString* sandbox_data = LoadSandboxTemplate(sandbox_type); | 478 NSString* sandbox_data = LoadSandboxTemplate(sandbox_type); |
530 if (!sandbox_data) { | 479 if (!sandbox_data) { |
531 return false; | 480 return false; |
532 } | 481 } |
533 | 482 |
534 SandboxVariableSubstitions substitutions; | 483 SandboxCompiler compiler([sandbox_data UTF8String]); |
| 484 |
535 if (!allowed_dir.empty()) { | 485 if (!allowed_dir.empty()) { |
536 // Add the sandbox commands necessary to access the given directory. | 486 // Add the sandbox parameters necessary to access the given directory. |
537 // Note: this function must be called before PostProcessSandboxProfile() | 487 base::FilePath allowed_dir_canonical = GetCanonicalSandboxPath(allowed_dir); |
538 // since the string it inserts contains variables that need substitution. | 488 std::string regex; |
539 NSString* allowed_dir_sandbox_command = | 489 if (!QuoteStringForRegex(allowed_dir_canonical.value(), ®ex)) { |
540 BuildAllowDirectoryAccessSandboxString(allowed_dir, &substitutions); | 490 FatalStringQuoteException(allowed_dir_canonical.value()); |
541 | 491 return false; |
542 if (allowed_dir_sandbox_command) { // May be nil if function fails. | |
543 sandbox_data = [sandbox_data | |
544 stringByReplacingOccurrencesOfString:@";ENABLE_DIRECTORY_ACCESS" | |
545 withString:allowed_dir_sandbox_command]; | |
546 } | 492 } |
| 493 if (!compiler.InsertStringParam("PERMITTED_DIR", regex)) |
| 494 return false; |
547 } | 495 } |
548 | 496 |
549 NSMutableArray* tokens_to_remove = [NSMutableArray array]; | |
550 | |
551 // Enable verbose logging if enabled on the command line. (See common.sb | 497 // Enable verbose logging if enabled on the command line. (See common.sb |
552 // for details). | 498 // for details). |
553 const base::CommandLine* command_line = | 499 const base::CommandLine* command_line = |
554 base::CommandLine::ForCurrentProcess(); | 500 base::CommandLine::ForCurrentProcess(); |
555 bool enable_logging = | 501 bool enable_logging = |
556 command_line->HasSwitch(switches::kEnableSandboxLogging);; | 502 command_line->HasSwitch(switches::kEnableSandboxLogging);; |
557 if (enable_logging) { | 503 if (!compiler.InsertBooleanParam("ENABLE_LOGGING", enable_logging)) |
558 [tokens_to_remove addObject:@";ENABLE_LOGGING"]; | 504 return false; |
559 } | |
560 | |
561 bool lion_or_later = base::mac::IsOSLionOrLater(); | |
562 | 505 |
563 // Without this, the sandbox will print a message to the system log every | 506 // Without this, the sandbox will print a message to the system log every |
564 // time it denies a request. This floods the console with useless spew. | 507 // time it denies a request. This floods the console with useless spew. |
565 if (!enable_logging) { | 508 if (!compiler.InsertBooleanParam("DISABLE_SANDBOX_DENIAL_LOGGING", |
566 substitutions["DISABLE_SANDBOX_DENIAL_LOGGING"] = | 509 !enable_logging)) |
567 SandboxSubstring("(with no-log)"); | 510 return false; |
568 } else { | |
569 substitutions["DISABLE_SANDBOX_DENIAL_LOGGING"] = SandboxSubstring(""); | |
570 } | |
571 | 511 |
572 // Splice the path of the user's home directory into the sandbox profile | 512 // Splice the path of the user's home directory into the sandbox profile |
573 // (see renderer.sb for details). | 513 // (see renderer.sb for details). |
574 std::string home_dir = [NSHomeDirectory() fileSystemRepresentation]; | 514 std::string home_dir = [NSHomeDirectory() fileSystemRepresentation]; |
575 | 515 |
576 base::FilePath home_dir_canonical = | 516 base::FilePath home_dir_canonical = |
577 GetCanonicalSandboxPath(base::FilePath(home_dir)); | 517 GetCanonicalSandboxPath(base::FilePath(home_dir)); |
578 | 518 |
579 substitutions["USER_HOMEDIR_AS_LITERAL"] = | 519 std::string quoted_home_dir; |
580 SandboxSubstring(home_dir_canonical.value(), | 520 if (!QuotePlainString(home_dir_canonical.value(), "ed_home_dir)) { |
581 SandboxSubstring::LITERAL); | 521 FatalStringQuoteException(home_dir_canonical.value()); |
582 | 522 return false; |
583 if (lion_or_later) { | |
584 // >=10.7 Sandbox rules. | |
585 [tokens_to_remove addObject:@";10.7_OR_ABOVE"]; | |
586 } | 523 } |
587 | 524 |
588 substitutions["COMPONENT_BUILD_WORKAROUND"] = SandboxSubstring(""); | 525 if (!compiler.InsertStringParam("USER_HOMEDIR_AS_LITERAL", quoted_home_dir)) |
| 526 return false; |
| 527 |
| 528 bool lion_or_later = base::mac::IsOSLionOrLater(); |
| 529 if (!compiler.InsertBooleanParam("LION_OR_LATER", lion_or_later)) |
| 530 return false; |
| 531 |
589 #if defined(COMPONENT_BUILD) | 532 #if defined(COMPONENT_BUILD) |
590 // dlopen() fails without file-read-metadata access if the executable image | 533 // dlopen() fails without file-read-metadata access if the executable image |
591 // contains LC_RPATH load commands. The components build uses those. | 534 // contains LC_RPATH load commands. The components build uses those. |
592 // See http://crbug.com/127465 | 535 // See http://crbug.com/127465 |
593 if (base::mac::IsOSSnowLeopard()) { | 536 if (base::mac::IsOSSnowLeopard()) { |
594 base::FilePath bundle_executable = base::mac::NSStringToFilePath( | 537 if (!compiler.InsertBooleanParam("COMPONENT_BUILD_WORKAROUND", true)) |
595 [base::mac::MainBundle() executablePath]); | 538 return false; |
596 NSString* sandbox_command = AllowMetadataForPath( | |
597 GetCanonicalSandboxPath(bundle_executable)); | |
598 substitutions["COMPONENT_BUILD_WORKAROUND"] = | |
599 SandboxSubstring(base::SysNSStringToUTF8(sandbox_command)); | |
600 } | 539 } |
601 #endif | 540 #endif |
602 | 541 |
603 // All information needed to assemble the final profile has been collected. | |
604 // Merge it all together. | |
605 std::string final_sandbox_profile_str; | |
606 if (!PostProcessSandboxProfile(sandbox_data, tokens_to_remove, substitutions, | |
607 &final_sandbox_profile_str)) { | |
608 return false; | |
609 } | |
610 | |
611 // Initialize sandbox. | 542 // Initialize sandbox. |
612 char* error_buff = NULL; | 543 std::string error_str; |
613 int error = sandbox_init(final_sandbox_profile_str.c_str(), 0, &error_buff); | 544 bool success = compiler.CompileAndApplyProfile(&error_str); |
614 bool success = (error == 0 && error_buff == NULL); | 545 DLOG_IF(FATAL, !success) << "Failed to initialize sandbox: " << error_str; |
615 DLOG_IF(FATAL, !success) << "Failed to initialize sandbox: " | |
616 << error | |
617 << " " | |
618 << error_buff; | |
619 sandbox_free_error(error_buff); | |
620 gSandboxIsActive = success; | 546 gSandboxIsActive = success; |
621 return success; | 547 return success; |
622 } | 548 } |
623 | 549 |
624 // static | 550 // static |
625 bool Sandbox::SandboxIsCurrentlyActive() { | 551 bool Sandbox::SandboxIsCurrentlyActive() { |
626 return gSandboxIsActive; | 552 return gSandboxIsActive; |
627 } | 553 } |
628 | 554 |
629 // static | 555 // static |
630 base::FilePath Sandbox::GetCanonicalSandboxPath(const base::FilePath& path) { | 556 base::FilePath Sandbox::GetCanonicalSandboxPath(const base::FilePath& path) { |
631 base::ScopedFD fd(HANDLE_EINTR(open(path.value().c_str(), O_RDONLY))); | 557 base::ScopedFD fd(HANDLE_EINTR(open(path.value().c_str(), O_RDONLY))); |
632 if (!fd.is_valid()) { | 558 if (!fd.is_valid()) { |
633 DPLOG(FATAL) << "GetCanonicalSandboxPath() failed for: " | 559 DPLOG(FATAL) << "GetCanonicalSandboxPath() failed for: " |
634 << path.value(); | 560 << path.value(); |
635 return path; | 561 return path; |
636 } | 562 } |
637 | 563 |
638 base::FilePath::CharType canonical_path[MAXPATHLEN]; | 564 base::FilePath::CharType canonical_path[MAXPATHLEN]; |
639 if (HANDLE_EINTR(fcntl(fd.get(), F_GETPATH, canonical_path)) != 0) { | 565 if (HANDLE_EINTR(fcntl(fd.get(), F_GETPATH, canonical_path)) != 0) { |
640 DPLOG(FATAL) << "GetCanonicalSandboxPath() failed for: " | 566 DPLOG(FATAL) << "GetCanonicalSandboxPath() failed for: " |
641 << path.value(); | 567 << path.value(); |
642 return path; | 568 return path; |
643 } | 569 } |
644 | 570 |
645 return base::FilePath(canonical_path); | 571 return base::FilePath(canonical_path); |
646 } | 572 } |
647 | 573 |
648 } // namespace content | 574 } // namespace content |
OLD | NEW |