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

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

Issue 4380001: Mac Sandbox: Clean up forward declaration of internal sandbox functions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleanup Created 10 years, 1 month 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
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" {
11 #include <sandbox.h> 11 #include <sandbox.h>
12 } 12 }
13 #include <sys/param.h> 13 #include <sys/param.h>
14 14
15 #include "base/basictypes.h" 15 #include "base/basictypes.h"
16 #include "base/command_line.h" 16 #include "base/command_line.h"
17 #include "base/file_util.h" 17 #include "base/file_util.h"
18 #include "base/hash_tables.h"
19 #include "base/mac_util.h" 18 #include "base/mac_util.h"
20 #include "base/rand_util_c.h" 19 #include "base/rand_util_c.h"
21 #include "base/mac/scoped_cftyperef.h" 20 #include "base/mac/scoped_cftyperef.h"
22 #include "base/mac/scoped_nsautorelease_pool.h" 21 #include "base/mac/scoped_nsautorelease_pool.h"
23 #include "base/string16.h" 22 #include "base/string16.h"
24 #include "base/string_util.h" 23 #include "base/string_util.h"
25 #include "base/sys_info.h" 24 #include "base/sys_info.h"
26 #include "base/sys_string_conversions.h" 25 #include "base/sys_string_conversions.h"
27 #include "base/utf_string_conversions.h" 26 #include "base/utf_string_conversions.h"
28 #include "chrome/common/chrome_switches.h" 27 #include "chrome/common/chrome_switches.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 } 62 }
64 63
65 dst->append(append); 64 dst->append(append);
66 return true; 65 return true;
67 } 66 }
68 67
69 } // namespace 68 } // namespace
70 69
71 namespace sandbox { 70 namespace sandbox {
72 71
73 // A map of variable name -> string to substitute in its place.
74 typedef base::hash_map<std::string, sandbox::SandboxSubstring>
75 SandboxVariableSubstitions;
76 72
77 // Escape |str_utf8| for use in a plain string variable in a sandbox 73 // static
78 // configuraton file. On return |dst| is set to the utf-8 encoded quoted 74 bool Sandbox::QuotePlainString(const std::string& str_utf8, std::string* dst) {
79 // output.
80 // Returns: true on success, false otherwise.
81 bool QuotePlainString(const std::string& str_utf8, std::string* dst) {
82 dst->clear(); 75 dst->clear();
83 76
84 const char* src = str_utf8.c_str(); 77 const char* src = str_utf8.c_str();
85 int32_t length = str_utf8.length(); 78 int32_t length = str_utf8.length();
86 int32_t position = 0; 79 int32_t position = 0;
87 while (position < length) { 80 while (position < length) {
88 UChar32 c; 81 UChar32 c;
89 U8_NEXT(src, position, length, c); // Macro increments |position|. 82 U8_NEXT(src, position, length, c); // Macro increments |position|.
90 DCHECK_GE(c, 0); 83 DCHECK_GE(c, 0);
91 if (c < 0) 84 if (c < 0)
(...skipping 14 matching lines...) Expand all
106 } 99 }
107 100
108 // If we got here we know that the character in question is strictly 101 // If we got here we know that the character in question is strictly
109 // in the ASCII range so there's no need to do any kind of encoding 102 // in the ASCII range so there's no need to do any kind of encoding
110 // conversion. 103 // conversion.
111 dst->push_back(static_cast<char>(c)); 104 dst->push_back(static_cast<char>(c));
112 } 105 }
113 return true; 106 return true;
114 } 107 }
115 108
116 // Escape |str_utf8| for use in a regex literal in a sandbox 109 // static
117 // configuraton file. On return |dst| is set to the utf-8 encoded quoted 110 bool Sandbox::QuoteStringForRegex(const std::string& str_utf8,
118 // output. 111 std::string* dst) {
119 //
120 // The implementation of this function is based on empirical testing of the
121 // OS X sandbox on 10.5.8 & 10.6.2 which is undocumented and subject to change.
122 //
123 // Note: If str_utf8 contains any characters < 32 || >125 then the function
124 // fails and false is returned.
125 //
126 // Returns: true on success, false otherwise.
127 bool QuoteStringForRegex(const std::string& str_utf8, std::string* dst) {
128 // Characters with special meanings in sandbox profile syntax. 112 // Characters with special meanings in sandbox profile syntax.
129 const char regex_special_chars[] = { 113 const char regex_special_chars[] = {
130 '\\', 114 '\\',
131 115
132 // Metacharacters 116 // Metacharacters
133 '^', 117 '^',
134 '.', 118 '.',
135 '[', 119 '[',
136 ']', 120 ']',
137 '$', 121 '$',
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 return true; 168 return true;
185 } 169 }
186 170
187 // Warm up System APIs that empirically need to be accessed before the Sandbox 171 // Warm up System APIs that empirically need to be accessed before the Sandbox
188 // is turned on. 172 // is turned on.
189 // This method is layed out in blocks, each one containing a separate function 173 // This method is layed out in blocks, each one containing a separate function
190 // that needs to be warmed up. The OS version on which we found the need to 174 // that needs to be warmed up. The OS version on which we found the need to
191 // enable the function is also noted. 175 // enable the function is also noted.
192 // This function is tested on the following OS versions: 176 // This function is tested on the following OS versions:
193 // 10.5.6, 10.6.0 177 // 10.5.6, 10.6.0
194 void SandboxWarmup() { 178
179 // static
180 void Sandbox::SandboxWarmup() {
195 base::mac::ScopedNSAutoreleasePool scoped_pool; 181 base::mac::ScopedNSAutoreleasePool scoped_pool;
196 182
197 { // CGColorSpaceCreateWithName(), CGBitmapContextCreate() - 10.5.6 183 { // CGColorSpaceCreateWithName(), CGBitmapContextCreate() - 10.5.6
198 base::mac::ScopedCFTypeRef<CGColorSpaceRef> rgb_colorspace( 184 base::mac::ScopedCFTypeRef<CGColorSpaceRef> rgb_colorspace(
199 CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); 185 CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB));
200 186
201 // Allocate a 1x1 image. 187 // Allocate a 1x1 image.
202 char data[4]; 188 char data[4];
203 base::mac::ScopedCFTypeRef<CGContextRef> context( 189 base::mac::ScopedCFTypeRef<CGContextRef> context(
204 CGBitmapContextCreate(data, 1, 1, 8, 1 * 4, 190 CGBitmapContextCreate(data, 1, 1, 8, 1 * 4,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 CGImageSourceCreateWithData((CFDataRef)data, 226 CGImageSourceCreateWithData((CFDataRef)data,
241 NULL)); 227 NULL));
242 CGImageSourceGetStatus(img); 228 CGImageSourceGetStatus(img);
243 } 229 }
244 230
245 { // Native Client access to /dev/random. 231 { // Native Client access to /dev/random.
246 GetUrandomFD(); 232 GetUrandomFD();
247 } 233 }
248 } 234 }
249 235
250 // Build the Sandbox command necessary to allow access to a named directory 236 // static
251 // indicated by |allowed_dir|. 237 NSString* Sandbox::BuildAllowDirectoryAccessSandboxString(
252 // Returns a string containing the sandbox profile commands necessary to allow
253 // access to that directory or nil if an error occured.
254
255 // The header comment for PostProcessSandboxProfile() explains how variable
256 // substition works in sandbox templates.
257 // The returned string contains embedded variables. The function fills in
258 // |substitutions| to contain the values for these variables.
259 NSString* BuildAllowDirectoryAccessSandboxString(
260 const FilePath& allowed_dir, 238 const FilePath& allowed_dir,
261 SandboxVariableSubstitions* substitutions) { 239 SandboxVariableSubstitions* substitutions) {
262 // A whitelist is used to determine which directories can be statted 240 // A whitelist is used to determine which directories can be statted
263 // This means that in the case of an /a/b/c/d/ directory, we may be able to 241 // This means that in the case of an /a/b/c/d/ directory, we may be able to
264 // stat the leaf directory, but not it's parent. 242 // stat the leaf directory, but not it's parent.
265 // The extension code in Chrome calls realpath() which fails if it can't call 243 // The extension code in Chrome calls realpath() which fails if it can't call
266 // stat() on one of the parent directories in the path. 244 // stat() on one of the parent directories in the path.
267 // The solution to this is to allow statting the parent directories themselves 245 // The solution to this is to allow statting the parent directories themselves
268 // but not their contents. We need to add a separate rule for each parent 246 // but not their contents. We need to add a separate rule for each parent
269 // directory. 247 // directory.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 SandboxSubstring::REGEX); 288 SandboxSubstring::REGEX);
311 sandbox_command = 289 sandbox_command =
312 [sandbox_command 290 [sandbox_command
313 stringByAppendingString:@") (allow file-read* file-write*" 291 stringByAppendingString:@") (allow file-read* file-write*"
314 " (regex #\"@ALLOWED_DIR@\") )"]; 292 " (regex #\"@ALLOWED_DIR@\") )"];
315 return sandbox_command; 293 return sandbox_command;
316 } 294 }
317 295
318 // Load the appropriate template for the given sandbox type. 296 // Load the appropriate template for the given sandbox type.
319 // Returns the template as an NSString or nil on error. 297 // Returns the template as an NSString or nil on error.
320 NSString* LoadSandboxTemplate(SandboxProcessType sandbox_type) { 298 NSString* LoadSandboxTemplate(Sandbox::SandboxProcessType sandbox_type) {
321 // We use a custom sandbox definition file to lock things down as 299 // We use a custom sandbox definition file to lock things down as
322 // tightly as possible. 300 // tightly as possible.
323 NSString* sandbox_config_filename = nil; 301 NSString* sandbox_config_filename = nil;
324 switch (sandbox_type) { 302 switch (sandbox_type) {
325 case SANDBOX_TYPE_RENDERER: 303 case Sandbox::SANDBOX_TYPE_RENDERER:
326 sandbox_config_filename = @"renderer"; 304 sandbox_config_filename = @"renderer";
327 break; 305 break;
328 case SANDBOX_TYPE_WORKER: 306 case Sandbox::SANDBOX_TYPE_WORKER:
329 sandbox_config_filename = @"worker"; 307 sandbox_config_filename = @"worker";
330 break; 308 break;
331 case SANDBOX_TYPE_UTILITY: 309 case Sandbox::SANDBOX_TYPE_UTILITY:
332 sandbox_config_filename = @"utility"; 310 sandbox_config_filename = @"utility";
333 break; 311 break;
334 case SANDBOX_TYPE_NACL_LOADER: 312 case Sandbox::SANDBOX_TYPE_NACL_LOADER:
335 // The Native Client loader is used for safeguarding the user's 313 // The Native Client loader is used for safeguarding the user's
336 // untrusted code within Native Client. 314 // untrusted code within Native Client.
337 sandbox_config_filename = @"nacl_loader"; 315 sandbox_config_filename = @"nacl_loader";
338 break; 316 break;
339 default: 317 default:
340 NOTREACHED(); 318 NOTREACHED();
341 return nil; 319 return nil;
342 } 320 }
343 321
344 // Read in the sandbox profile and the common prefix file. 322 // Read in the sandbox profile and the common prefix file.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 // Retrieve OS X version, output parameters are self explanatory. 355 // Retrieve OS X version, output parameters are self explanatory.
378 void GetOSVersion(bool* snow_leopard_or_higher) { 356 void GetOSVersion(bool* snow_leopard_or_higher) {
379 int32 major_version, minor_version, bugfix_version; 357 int32 major_version, minor_version, bugfix_version;
380 base::SysInfo::OperatingSystemVersionNumbers(&major_version, 358 base::SysInfo::OperatingSystemVersionNumbers(&major_version,
381 &minor_version, 359 &minor_version,
382 &bugfix_version); 360 &bugfix_version);
383 *snow_leopard_or_higher = 361 *snow_leopard_or_higher =
384 (major_version > 10 || (major_version == 10 && minor_version >= 6)); 362 (major_version > 10 || (major_version == 10 && minor_version >= 6));
385 } 363 }
386 364
387 // Assemble the final sandbox profile from a template by removing comments 365 // static
388 // and substituting variables. 366 bool Sandbox::PostProcessSandboxProfile(
389 // 367 NSString* sandbox_template,
390 // |sandbox_template| is a string which contains 2 entitites to operate on: 368 NSArray* comments_to_remove,
391 // 369 SandboxVariableSubstitions& substitutions,
392 // - Comments - The sandbox comment syntax is used to make the OS sandbox 370 std::string *final_sandbox_profile_str) {
393 // optionally ignore commands it doesn't support. e.g.
394 // ;10.6_ONLY (foo)
395 // Where (foo) is some command that is only supported on OS X 10.6.
396 // The ;10.6_ONLY comment can then be removed from the template to enable (foo)
397 // as appropriate.
398 //
399 // - Variables - denoted by @variable_name@ . These are defined in the sandbox
400 // template in cases where another string needs to be substituted at runtime.
401 // e.g. @HOMEDIR_AS_LITERAL@ is substituted at runtime for the user's home
402 // directory escaped appropriately for a (literal ...) expression.
403 //
404 // |comments_to_remove| is a list of NSStrings containing the comments to
405 // remove.
406 // |substitutions| is a hash of "variable name" -> "string to substitute".
407 // Where the replacement string is tagged with information on how it is to be
408 // escaped e.g. used as part of a regex string or a literal.
409 //
410 // On output |final_sandbox_profile_str| contains the final sandbox profile.
411 // Returns true on success, false otherwise.
412 bool PostProcessSandboxProfile(NSString* sandbox_template,
413 NSArray* comments_to_remove,
414 SandboxVariableSubstitions& substitutions,
415 std::string *final_sandbox_profile_str) {
416 NSString* sandbox_data = [[sandbox_template copy] autorelease]; 371 NSString* sandbox_data = [[sandbox_template copy] autorelease];
417 372
418 // Remove comments, e.g. ;10.6_ONLY . 373 // Remove comments, e.g. ;10.6_ONLY .
419 for (NSString* to_remove in comments_to_remove) { 374 for (NSString* to_remove in comments_to_remove) {
420 sandbox_data = [sandbox_data stringByReplacingOccurrencesOfString:to_remove 375 sandbox_data = [sandbox_data stringByReplacingOccurrencesOfString:to_remove
421 withString:@""]; 376 withString:@""];
422 } 377 }
423 378
424 // Split string on "@" characters. 379 // Split string on "@" characters.
425 std::vector<std::string> raw_sandbox_pieces; 380 std::vector<std::string> raw_sandbox_pieces;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 for (std::vector<std::string>::iterator it = processed_sandbox_pieces.begin(); 423 for (std::vector<std::string>::iterator it = processed_sandbox_pieces.begin();
469 it != processed_sandbox_pieces.end(); 424 it != processed_sandbox_pieces.end();
470 ++it) { 425 ++it) {
471 final_sandbox_profile_str->append(*it); 426 final_sandbox_profile_str->append(*it);
472 } 427 }
473 return true; 428 return true;
474 } 429 }
475 430
476 431
477 // Turns on the OS X sandbox for this process. 432 // Turns on the OS X sandbox for this process.
478 bool EnableSandbox(SandboxProcessType sandbox_type, 433
479 const FilePath& allowed_dir) { 434 // static
435 bool Sandbox::EnableSandbox(SandboxProcessType sandbox_type,
436 const FilePath& allowed_dir) {
480 // Sanity - currently only SANDBOX_TYPE_UTILITY supports a directory being 437 // Sanity - currently only SANDBOX_TYPE_UTILITY supports a directory being
481 // passed in. 438 // passed in.
482 if (sandbox_type != SANDBOX_TYPE_UTILITY) { 439 if (sandbox_type != SANDBOX_TYPE_UTILITY) {
483 DCHECK(allowed_dir.empty()) 440 DCHECK(allowed_dir.empty())
484 << "Only SANDBOX_TYPE_UTILITY allows a custom directory parameter."; 441 << "Only SANDBOX_TYPE_UTILITY allows a custom directory parameter.";
485 } 442 }
486 443
487 NSString* sandbox_data = LoadSandboxTemplate(sandbox_type); 444 NSString* sandbox_data = LoadSandboxTemplate(sandbox_type);
488 if (!sandbox_data) { 445 if (!sandbox_data) {
489 return false; 446 return false;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 int error = sandbox_init(final_sandbox_profile_str.c_str(), 0, &error_buff); 520 int error = sandbox_init(final_sandbox_profile_str.c_str(), 0, &error_buff);
564 bool success = (error == 0 && error_buff == NULL); 521 bool success = (error == 0 && error_buff == NULL);
565 LOG_IF(FATAL, !success) << "Failed to initialize sandbox: " 522 LOG_IF(FATAL, !success) << "Failed to initialize sandbox: "
566 << error 523 << error
567 << " " 524 << " "
568 << error_buff; 525 << error_buff;
569 sandbox_free_error(error_buff); 526 sandbox_free_error(error_buff);
570 return success; 527 return success;
571 } 528 }
572 529
573 void GetCanonicalSandboxPath(FilePath* path) { 530 // static
531 void Sandbox::GetCanonicalSandboxPath(FilePath* path) {
574 int fd = HANDLE_EINTR(open(path->value().c_str(), O_RDONLY)); 532 int fd = HANDLE_EINTR(open(path->value().c_str(), O_RDONLY));
575 if (fd < 0) { 533 if (fd < 0) {
576 PLOG(FATAL) << "GetCanonicalSandboxPath() failed for: " 534 PLOG(FATAL) << "GetCanonicalSandboxPath() failed for: "
577 << path->value(); 535 << path->value();
578 return; 536 return;
579 } 537 }
580 file_util::ScopedFD file_closer(&fd); 538 file_util::ScopedFD file_closer(&fd);
581 539
582 FilePath::CharType canonical_path[MAXPATHLEN]; 540 FilePath::CharType canonical_path[MAXPATHLEN];
583 if (HANDLE_EINTR(fcntl(fd, F_GETPATH, canonical_path)) != 0) { 541 if (HANDLE_EINTR(fcntl(fd, F_GETPATH, canonical_path)) != 0) {
584 PLOG(FATAL) << "GetCanonicalSandboxPath() failed for: " 542 PLOG(FATAL) << "GetCanonicalSandboxPath() failed for: "
585 << path->value(); 543 << path->value();
586 return; 544 return;
587 } 545 }
588 546
589 *path = FilePath(canonical_path); 547 *path = FilePath(canonical_path);
590 } 548 }
591 549
592 } // namespace sandbox 550 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698