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 |