Chromium Code Reviews| 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_mac.h" | 5 #include "content/common/sandbox_mac.h" |
| 6 | 6 |
| 7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
| 8 | 8 |
| 9 extern "C" { | 9 extern "C" { |
| 10 #include <sandbox.h> | 10 #include <sandbox.h> |
| 11 } | 11 } |
| 12 #include <signal.h> | 12 #include <signal.h> |
| 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/compiler_specific.h" | 17 #include "base/compiler_specific.h" |
| 18 #include "base/file_util.h" | 18 #include "base/file_util.h" |
| 19 #include "base/mac/mac_util.h" | 19 #include "base/mac/mac_util.h" |
| 20 #include "base/rand_util_c.h" | 20 #include "base/rand_util_c.h" |
| 21 #include "base/mac/scoped_cftyperef.h" | 21 #include "base/mac/scoped_cftyperef.h" |
| 22 #include "base/mac/scoped_nsautorelease_pool.h" | 22 #include "base/mac/scoped_nsautorelease_pool.h" |
| 23 #include "base/string16.h" | 23 #include "base/string16.h" |
| 24 #include "base/string_piece.h" | |
| 24 #include "base/string_util.h" | 25 #include "base/string_util.h" |
| 25 #include "base/stringprintf.h" | 26 #include "base/stringprintf.h" |
| 26 #include "base/sys_info.h" | 27 #include "base/sys_info.h" |
| 27 #include "base/sys_string_conversions.h" | 28 #include "base/sys_string_conversions.h" |
| 28 #include "base/utf_string_conversions.h" | 29 #include "base/utf_string_conversions.h" |
| 29 #include "content/common/chrome_application_mac.h" | 30 #include "content/common/chrome_application_mac.h" |
| 31 #include "content/public/common/content_client.h" | |
| 30 #include "content/public/common/content_switches.h" | 32 #include "content/public/common/content_switches.h" |
| 33 #include "grit/content_resources.h" | |
|
jam
2011/11/17 01:50:46
initially when separating content from chrome, we
| |
| 31 #include "unicode/uchar.h" | 34 #include "unicode/uchar.h" |
| 32 #include "ui/gfx/gl/gl_surface.h" | 35 #include "ui/gfx/gl/gl_surface.h" |
| 33 | 36 |
| 34 namespace { | 37 namespace { |
| 35 | 38 |
| 36 // Try to escape |c| as a "SingleEscapeCharacter" (\n, etc). If successful, | 39 // Try to escape |c| as a "SingleEscapeCharacter" (\n, etc). If successful, |
| 37 // returns true and appends the escape sequence to |dst|. | 40 // returns true and appends the escape sequence to |dst|. |
| 38 bool EscapeSingleChar(char c, std::string* dst) { | 41 bool EscapeSingleChar(char c, std::string* dst) { |
| 39 const char *append = NULL; | 42 const char *append = NULL; |
| 40 switch (c) { | 43 switch (c) { |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 183 | 186 |
| 184 // Warm up System APIs that empirically need to be accessed before the Sandbox | 187 // Warm up System APIs that empirically need to be accessed before the Sandbox |
| 185 // is turned on. | 188 // is turned on. |
| 186 // This method is layed out in blocks, each one containing a separate function | 189 // This method is layed out in blocks, each one containing a separate function |
| 187 // that needs to be warmed up. The OS version on which we found the need to | 190 // that needs to be warmed up. The OS version on which we found the need to |
| 188 // enable the function is also noted. | 191 // enable the function is also noted. |
| 189 // This function is tested on the following OS versions: | 192 // This function is tested on the following OS versions: |
| 190 // 10.5.6, 10.6.0 | 193 // 10.5.6, 10.6.0 |
| 191 | 194 |
| 192 // static | 195 // static |
| 193 void Sandbox::SandboxWarmup(SandboxProcessType sandbox_type) { | 196 void Sandbox::SandboxWarmup(int sandbox_definition_resource_id) { |
| 194 base::mac::ScopedNSAutoreleasePool scoped_pool; | 197 base::mac::ScopedNSAutoreleasePool scoped_pool; |
| 195 | 198 |
| 196 { // CGColorSpaceCreateWithName(), CGBitmapContextCreate() - 10.5.6 | 199 { // CGColorSpaceCreateWithName(), CGBitmapContextCreate() - 10.5.6 |
| 197 base::mac::ScopedCFTypeRef<CGColorSpaceRef> rgb_colorspace( | 200 base::mac::ScopedCFTypeRef<CGColorSpaceRef> rgb_colorspace( |
| 198 CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); | 201 CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); |
| 199 | 202 |
| 200 // Allocate a 1x1 image. | 203 // Allocate a 1x1 image. |
| 201 char data[4]; | 204 char data[4]; |
| 202 base::mac::ScopedCFTypeRef<CGContextRef> context( | 205 base::mac::ScopedCFTypeRef<CGContextRef> context( |
| 203 CGBitmapContextCreate(data, 1, 1, 8, 1 * 4, | 206 CGBitmapContextCreate(data, 1, 1, 8, 1 * 4, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 NULL)); | 243 NULL)); |
| 241 CGImageSourceGetStatus(img); | 244 CGImageSourceGetStatus(img); |
| 242 } | 245 } |
| 243 | 246 |
| 244 { | 247 { |
| 245 // Allow access to /dev/urandom. | 248 // Allow access to /dev/urandom. |
| 246 GetUrandomFD(); | 249 GetUrandomFD(); |
| 247 } | 250 } |
| 248 | 251 |
| 249 // Process-type dependent warm-up. | 252 // Process-type dependent warm-up. |
| 250 switch (sandbox_type) { | 253 if (sandbox_definition_resource_id == IDR_GPU_SANDBOX_DEFINITION) { |
| 251 case SANDBOX_TYPE_GPU: | 254 // Preload either the desktop GL or the osmesa so, depending on the |
| 252 { | 255 // --use-gl flag. |
| 253 // Preload either the desktop GL or the osmesa so, depending on the | 256 gfx::GLSurface::InitializeOneOff(); |
| 254 // --use-gl flag. | |
| 255 gfx::GLSurface::InitializeOneOff(); | |
| 256 } | |
| 257 break; | |
| 258 | |
| 259 default: | |
| 260 // To shut up a gcc warning. | |
| 261 break; | |
| 262 } | 257 } |
| 263 } | 258 } |
| 264 | 259 |
| 265 // static | 260 // static |
| 266 NSString* Sandbox::BuildAllowDirectoryAccessSandboxString( | 261 NSString* Sandbox::BuildAllowDirectoryAccessSandboxString( |
| 267 const FilePath& allowed_dir, | 262 const FilePath& allowed_dir, |
| 268 SandboxVariableSubstitions* substitutions) { | 263 SandboxVariableSubstitions* substitutions) { |
| 269 // A whitelist is used to determine which directories can be statted | 264 // A whitelist is used to determine which directories can be statted |
| 270 // This means that in the case of an /a/b/c/d/ directory, we may be able to | 265 // This means that in the case of an /a/b/c/d/ directory, we may be able to |
| 271 // stat the leaf directory, but not it's parent. | 266 // stat the leaf directory, but not it's parent. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 SandboxSubstring::REGEX); | 312 SandboxSubstring::REGEX); |
| 318 sandbox_command = | 313 sandbox_command = |
| 319 [sandbox_command | 314 [sandbox_command |
| 320 stringByAppendingString:@") (allow file-read* file-write*" | 315 stringByAppendingString:@") (allow file-read* file-write*" |
| 321 " (regex #\"@ALLOWED_DIR@\") )"]; | 316 " (regex #\"@ALLOWED_DIR@\") )"]; |
| 322 return sandbox_command; | 317 return sandbox_command; |
| 323 } | 318 } |
| 324 | 319 |
| 325 // Load the appropriate template for the given sandbox type. | 320 // Load the appropriate template for the given sandbox type. |
| 326 // Returns the template as an NSString or nil on error. | 321 // Returns the template as an NSString or nil on error. |
| 327 NSString* LoadSandboxTemplate(Sandbox::SandboxProcessType sandbox_type) { | 322 NSString* LoadSandboxTemplate(int sandbox_definition_resource_id) { |
| 328 // We use a custom sandbox definition file to lock things down as | 323 // We use a custom sandbox definition to lock things down as tightly as |
| 329 // tightly as possible. | 324 // possible. |
| 330 NSString* sandbox_config_filename = nil; | 325 base::StringPiece sandbox_definition = |
| 331 switch (sandbox_type) { | 326 content::GetContentClient()->GetDataResource( |
| 332 case Sandbox::SANDBOX_TYPE_RENDERER: | 327 sandbox_definition_resource_id); |
| 333 sandbox_config_filename = @"renderer"; | 328 if (sandbox_definition.empty()) { |
| 334 break; | 329 DLOG(FATAL) << "Failed to load the sandbox profile (resource id " |
| 335 case Sandbox::SANDBOX_TYPE_WORKER: | 330 << sandbox_definition_resource_id << ")"; |
| 336 sandbox_config_filename = @"worker"; | |
| 337 break; | |
| 338 case Sandbox::SANDBOX_TYPE_UTILITY: | |
| 339 sandbox_config_filename = @"utility"; | |
| 340 break; | |
| 341 case Sandbox::SANDBOX_TYPE_NACL_LOADER: | |
| 342 // The Native Client loader is used for safeguarding the user's | |
| 343 // untrusted code within Native Client. | |
| 344 sandbox_config_filename = @"nacl_loader"; | |
| 345 break; | |
| 346 case Sandbox::SANDBOX_TYPE_GPU: | |
| 347 sandbox_config_filename = @"gpu"; | |
| 348 break; | |
| 349 case Sandbox::SANDBOX_TYPE_PPAPI: | |
| 350 sandbox_config_filename = @"ppapi"; | |
| 351 break; | |
| 352 default: | |
| 353 NOTREACHED(); | |
| 354 return nil; | |
| 355 } | |
| 356 | |
| 357 // Read in the sandbox profile and the common prefix file. | |
| 358 NSString* common_sandbox_prefix_path = | |
| 359 [base::mac::MainAppBundle() pathForResource:@"common" | |
| 360 ofType:@"sb"]; | |
| 361 NSString* common_sandbox_prefix_data = | |
| 362 [NSString stringWithContentsOfFile:common_sandbox_prefix_path | |
| 363 encoding:NSUTF8StringEncoding | |
| 364 error:NULL]; | |
| 365 | |
| 366 if (!common_sandbox_prefix_data) { | |
| 367 DLOG(FATAL) << "Failed to find the sandbox profile on disk " | |
| 368 << [common_sandbox_prefix_path fileSystemRepresentation]; | |
| 369 return nil; | 331 return nil; |
| 370 } | 332 } |
| 371 | 333 |
| 372 NSString* sandbox_profile_path = | 334 base::StringPiece common_sandbox_definition = |
| 373 [base::mac::MainAppBundle() pathForResource:sandbox_config_filename | 335 content::GetContentClient()->GetDataResource( |
| 374 ofType:@"sb"]; | 336 IDR_COMMON_SANDBOX_DEFINITION); |
| 375 NSString* sandbox_data = | 337 if (common_sandbox_definition.empty()) { |
| 376 [NSString stringWithContentsOfFile:sandbox_profile_path | 338 DLOG(FATAL) << "Failed to load the common sandbox profile"; |
| 377 encoding:NSUTF8StringEncoding | |
| 378 error:NULL]; | |
| 379 | |
| 380 if (!sandbox_data) { | |
| 381 DLOG(FATAL) << "Failed to find the sandbox profile on disk " | |
| 382 << [sandbox_profile_path fileSystemRepresentation]; | |
| 383 return nil; | 339 return nil; |
| 384 } | 340 } |
| 385 | 341 |
| 342 NSString* common_sandbox_prefix_data = | |
| 343 [[NSString alloc] initWithBytes:common_sandbox_definition.data() | |
| 344 length:common_sandbox_definition.length() | |
| 345 encoding:NSUTF8StringEncoding]; | |
| 346 | |
| 347 NSString* sandbox_data = | |
| 348 [[NSString alloc] initWithBytes:sandbox_definition.data() | |
| 349 length:sandbox_definition.length() | |
| 350 encoding:NSUTF8StringEncoding]; | |
| 351 | |
| 352 | |
| 386 // Prefix sandbox_data with common_sandbox_prefix_data. | 353 // Prefix sandbox_data with common_sandbox_prefix_data. |
| 387 return [common_sandbox_prefix_data stringByAppendingString:sandbox_data]; | 354 return [common_sandbox_prefix_data stringByAppendingString:sandbox_data]; |
| 388 } | 355 } |
| 389 | 356 |
| 390 // static | 357 // static |
| 391 bool Sandbox::PostProcessSandboxProfile( | 358 bool Sandbox::PostProcessSandboxProfile( |
| 392 NSString* sandbox_template, | 359 NSString* sandbox_template, |
| 393 NSArray* comments_to_remove, | 360 NSArray* comments_to_remove, |
| 394 SandboxVariableSubstitions& substitutions, | 361 SandboxVariableSubstitions& substitutions, |
| 395 std::string *final_sandbox_profile_str) { | 362 std::string *final_sandbox_profile_str) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 452 ++it) { | 419 ++it) { |
| 453 final_sandbox_profile_str->append(*it); | 420 final_sandbox_profile_str->append(*it); |
| 454 } | 421 } |
| 455 return true; | 422 return true; |
| 456 } | 423 } |
| 457 | 424 |
| 458 | 425 |
| 459 // Turns on the OS X sandbox for this process. | 426 // Turns on the OS X sandbox for this process. |
| 460 | 427 |
| 461 // static | 428 // static |
| 462 bool Sandbox::EnableSandbox(SandboxProcessType sandbox_type, | 429 bool Sandbox::EnableSandbox(int sandbox_definition_resource_id, |
| 463 const FilePath& allowed_dir) { | 430 const FilePath& allowed_dir) { |
| 464 // Sanity - currently only SANDBOX_TYPE_UTILITY supports a directory being | 431 // Sanity - currently only IDR_UTILITY_SANDBOX_DEFINITION supports a |
| 465 // passed in. | 432 // directory being passed in. |
| 466 if (sandbox_type != SANDBOX_TYPE_UTILITY) { | 433 if (sandbox_definition_resource_id != IDR_UTILITY_SANDBOX_DEFINITION) { |
| 467 DCHECK(allowed_dir.empty()) | 434 DCHECK(allowed_dir.empty()) << "Only IDR_UTILITY_SANDBOX_DEFINITION allows" |
| 468 << "Only SANDBOX_TYPE_UTILITY allows a custom directory parameter."; | 435 << " a custom directory parameter."; |
| 469 } | 436 } |
| 470 | 437 |
| 471 NSString* sandbox_data = LoadSandboxTemplate(sandbox_type); | 438 NSString* sandbox_data = LoadSandboxTemplate(sandbox_definition_resource_id); |
| 472 if (!sandbox_data) { | 439 if (!sandbox_data) { |
| 473 return false; | 440 return false; |
| 474 } | 441 } |
| 475 | 442 |
| 476 SandboxVariableSubstitions substitutions; | 443 SandboxVariableSubstitions substitutions; |
| 477 if (!allowed_dir.empty()) { | 444 if (!allowed_dir.empty()) { |
| 478 // Add the sandbox commands necessary to access the given directory. | 445 // Add the sandbox commands necessary to access the given directory. |
| 479 // Note: this function must be called before PostProcessSandboxProfile() | 446 // Note: this function must be called before PostProcessSandboxProfile() |
| 480 // since the string it inserts contains variables that need substitution. | 447 // since the string it inserts contains variables that need substitution. |
| 481 NSString* allowed_dir_sandbox_command = | 448 NSString* allowed_dir_sandbox_command = |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 570 if (HANDLE_EINTR(fcntl(fd, F_GETPATH, canonical_path)) != 0) { | 537 if (HANDLE_EINTR(fcntl(fd, F_GETPATH, canonical_path)) != 0) { |
| 571 DPLOG(FATAL) << "GetCanonicalSandboxPath() failed for: " | 538 DPLOG(FATAL) << "GetCanonicalSandboxPath() failed for: " |
| 572 << path->value(); | 539 << path->value(); |
| 573 return; | 540 return; |
| 574 } | 541 } |
| 575 | 542 |
| 576 *path = FilePath(canonical_path); | 543 *path = FilePath(canonical_path); |
| 577 } | 544 } |
| 578 | 545 |
| 579 } // namespace sandbox | 546 } // namespace sandbox |
| OLD | NEW |