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

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

Issue 8589001: Load mac sandbox definitions from resources instead of the bundle. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: different approach Created 9 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) 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"
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
39 struct SandboxProcessTypePolicyMapping {
40 content::SandboxProcessType sandbox_process_type;
41 int sandbox_policy_resource_id;
42 };
43
44 // Mapping from sandbox process types to resource IDs defining the sandbox
45 // policy for all process types known to content.
46 SandboxProcessTypePolicyMapping kDefaultSandboxProcessTypePolicyMapping[] = {
47 { content::SANDBOX_TYPE_RENDERER, IDR_RENDERER_SANDBOX_POLICY },
48 { content::SANDBOX_TYPE_WORKER, IDR_WORKER_SANDBOX_POLICY },
49 { content::SANDBOX_TYPE_UTILITY, IDR_UTILITY_SANDBOX_POLICY },
50 { content::SANDBOX_TYPE_GPU, IDR_GPU_SANDBOX_POLICY },
51 { content::SANDBOX_TYPE_PPAPI, IDR_PPAPI_SANDBOX_POLICY },
52 };
53
54 COMPILE_ASSERT(arraysize(kDefaultSandboxProcessTypePolicyMapping) == \
55 size_t(content::SANDBOX_AFTER_TYPE_LAST_TYPE), \
56 sandbox_process_type_policy_map_incorrect);
57
36 // Try to escape |c| as a "SingleEscapeCharacter" (\n, etc). If successful, 58 // Try to escape |c| as a "SingleEscapeCharacter" (\n, etc). If successful,
37 // returns true and appends the escape sequence to |dst|. 59 // returns true and appends the escape sequence to |dst|.
38 bool EscapeSingleChar(char c, std::string* dst) { 60 bool EscapeSingleChar(char c, std::string* dst) {
39 const char *append = NULL; 61 const char *append = NULL;
40 switch (c) { 62 switch (c) {
41 case '\b': 63 case '\b':
42 append = "\\b"; 64 append = "\\b";
43 break; 65 break;
44 case '\f': 66 case '\f':
45 append = "\\f"; 67 append = "\\f";
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 205
184 // Warm up System APIs that empirically need to be accessed before the Sandbox 206 // Warm up System APIs that empirically need to be accessed before the Sandbox
185 // is turned on. 207 // is turned on.
186 // This method is layed out in blocks, each one containing a separate function 208 // 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 209 // that needs to be warmed up. The OS version on which we found the need to
188 // enable the function is also noted. 210 // enable the function is also noted.
189 // This function is tested on the following OS versions: 211 // This function is tested on the following OS versions:
190 // 10.5.6, 10.6.0 212 // 10.5.6, 10.6.0
191 213
192 // static 214 // static
193 void Sandbox::SandboxWarmup(SandboxProcessType sandbox_type) { 215 void Sandbox::SandboxWarmup(int sandbox_type) {
194 base::mac::ScopedNSAutoreleasePool scoped_pool; 216 base::mac::ScopedNSAutoreleasePool scoped_pool;
195 217
196 { // CGColorSpaceCreateWithName(), CGBitmapContextCreate() - 10.5.6 218 { // CGColorSpaceCreateWithName(), CGBitmapContextCreate() - 10.5.6
197 base::mac::ScopedCFTypeRef<CGColorSpaceRef> rgb_colorspace( 219 base::mac::ScopedCFTypeRef<CGColorSpaceRef> rgb_colorspace(
198 CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); 220 CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB));
199 221
200 // Allocate a 1x1 image. 222 // Allocate a 1x1 image.
201 char data[4]; 223 char data[4];
202 base::mac::ScopedCFTypeRef<CGContextRef> context( 224 base::mac::ScopedCFTypeRef<CGContextRef> context(
203 CGBitmapContextCreate(data, 1, 1, 8, 1 * 4, 225 CGBitmapContextCreate(data, 1, 1, 8, 1 * 4,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 NULL)); 262 NULL));
241 CGImageSourceGetStatus(img); 263 CGImageSourceGetStatus(img);
242 } 264 }
243 265
244 { 266 {
245 // Allow access to /dev/urandom. 267 // Allow access to /dev/urandom.
246 GetUrandomFD(); 268 GetUrandomFD();
247 } 269 }
248 270
249 // Process-type dependent warm-up. 271 // Process-type dependent warm-up.
250 switch (sandbox_type) { 272 if (sandbox_type == content::SANDBOX_TYPE_GPU) {
251 case SANDBOX_TYPE_GPU: 273 // Preload either the desktop GL or the osmesa so, depending on the
252 { 274 // --use-gl flag.
253 // Preload either the desktop GL or the osmesa so, depending on the 275 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 } 276 }
263 } 277 }
264 278
265 // static 279 // static
266 NSString* Sandbox::BuildAllowDirectoryAccessSandboxString( 280 NSString* Sandbox::BuildAllowDirectoryAccessSandboxString(
267 const FilePath& allowed_dir, 281 const FilePath& allowed_dir,
268 SandboxVariableSubstitions* substitutions) { 282 SandboxVariableSubstitions* substitutions) {
269 // A whitelist is used to determine which directories can be statted 283 // 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 284 // 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. 285 // stat the leaf directory, but not it's parent.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 SandboxSubstring::REGEX); 331 SandboxSubstring::REGEX);
318 sandbox_command = 332 sandbox_command =
319 [sandbox_command 333 [sandbox_command
320 stringByAppendingString:@") (allow file-read* file-write*" 334 stringByAppendingString:@") (allow file-read* file-write*"
321 " (regex #\"@ALLOWED_DIR@\") )"]; 335 " (regex #\"@ALLOWED_DIR@\") )"];
322 return sandbox_command; 336 return sandbox_command;
323 } 337 }
324 338
325 // Load the appropriate template for the given sandbox type. 339 // Load the appropriate template for the given sandbox type.
326 // Returns the template as an NSString or nil on error. 340 // Returns the template as an NSString or nil on error.
327 NSString* LoadSandboxTemplate(Sandbox::SandboxProcessType sandbox_type) { 341 NSString* LoadSandboxTemplate(int sandbox_type) {
jeremy 2011/11/23 07:02:17 Can you add a CHECK() here or in an appropriate pl
jochen (gone - plz use gerrit) 2011/11/23 10:57:28 Done.
328 // We use a custom sandbox definition file to lock things down as 342 // We use a custom sandbox definition to lock things down as tightly as
329 // tightly as possible. 343 // possible.
330 NSString* sandbox_config_filename = nil; 344 int sandbox_policy_resource_id = -1;
331 switch (sandbox_type) { 345
332 case Sandbox::SANDBOX_TYPE_RENDERER: 346 for (size_t i = 0;
jeremy 2011/11/23 07:02:17 // Find resource id for sandbox profile to use for
jochen (gone - plz use gerrit) 2011/11/23 10:57:28 Done.
333 sandbox_config_filename = @"renderer"; 347 i < arraysize(kDefaultSandboxProcessTypePolicyMapping);
348 ++i) {
349 if (kDefaultSandboxProcessTypePolicyMapping[i].sandbox_process_type ==
350 sandbox_type) {
351 sandbox_policy_resource_id =
352 kDefaultSandboxProcessTypePolicyMapping[i].sandbox_policy_resource_id;
334 break; 353 break;
335 case Sandbox::SANDBOX_TYPE_WORKER: 354 }
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 } 355 }
356 356 if (sandbox_policy_resource_id == -1) {
357 // Read in the sandbox profile and the common prefix file. 357 // See if the embedder knows about this sandbox process type.
jeremy 2011/11/23 07:02:17 *See->Check
jochen (gone - plz use gerrit) 2011/11/23 10:57:28 Done.
358 NSString* common_sandbox_prefix_path = 358 sandbox_policy_resource_id = content::GetContentClient()->
359 [base::mac::MainAppBundle() pathForResource:@"common" 359 GetSandboxPolicyForSandboxType(sandbox_type);
360 ofType:@"sb"]; 360 }
361 NSString* common_sandbox_prefix_data = 361 if (sandbox_policy_resource_id == -1) {
362 [NSString stringWithContentsOfFile:common_sandbox_prefix_path 362 DLOG(FATAL) << "Unknown sandbox type " << sandbox_type;
jeremy 2011/11/23 07:02:17 LOG_IF() errors here should always be fatal, I kno
jochen (gone - plz use gerrit) 2011/11/23 10:57:28 I turned this into a CHECK
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; 363 return nil;
370 } 364 }
371 365
372 NSString* sandbox_profile_path = 366 base::StringPiece sandbox_definition =
373 [base::mac::MainAppBundle() pathForResource:sandbox_config_filename 367 content::GetContentClient()->GetDataResource(sandbox_policy_resource_id);
374 ofType:@"sb"]; 368 if (sandbox_definition.empty()) {
375 NSString* sandbox_data = 369 DLOG(FATAL) << "Failed to load the sandbox profile (resource id "
jeremy 2011/11/23 07:02:17 *DLOG -> LOG
jochen (gone - plz use gerrit) 2011/11/23 10:57:28 Done.
376 [NSString stringWithContentsOfFile:sandbox_profile_path 370 << sandbox_policy_resource_id << ")";
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; 371 return nil;
384 } 372 }
385 373
374 base::StringPiece common_sandbox_definition =
375 content::GetContentClient()->GetDataResource(IDR_COMMON_SANDBOX_POLICY);
376 if (common_sandbox_definition.empty()) {
377 DLOG(FATAL) << "Failed to load the common sandbox profile";
378 return nil;
379 }
380
381 NSString* common_sandbox_prefix_data =
382 [[NSString alloc] initWithBytes:common_sandbox_definition.data()
383 length:common_sandbox_definition.length()
384 encoding:NSUTF8StringEncoding];
385
386 NSString* sandbox_data =
387 [[NSString alloc] initWithBytes:sandbox_definition.data()
388 length:sandbox_definition.length()
389 encoding:NSUTF8StringEncoding];
390
386 // Prefix sandbox_data with common_sandbox_prefix_data. 391 // Prefix sandbox_data with common_sandbox_prefix_data.
387 return [common_sandbox_prefix_data stringByAppendingString:sandbox_data]; 392 return [common_sandbox_prefix_data stringByAppendingString:sandbox_data];
388 } 393 }
389 394
390 // static 395 // static
391 bool Sandbox::PostProcessSandboxProfile( 396 bool Sandbox::PostProcessSandboxProfile(
392 NSString* sandbox_template, 397 NSString* sandbox_template,
393 NSArray* comments_to_remove, 398 NSArray* comments_to_remove,
394 SandboxVariableSubstitions& substitutions, 399 SandboxVariableSubstitions& substitutions,
395 std::string *final_sandbox_profile_str) { 400 std::string *final_sandbox_profile_str) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 ++it) { 457 ++it) {
453 final_sandbox_profile_str->append(*it); 458 final_sandbox_profile_str->append(*it);
454 } 459 }
455 return true; 460 return true;
456 } 461 }
457 462
458 463
459 // Turns on the OS X sandbox for this process. 464 // Turns on the OS X sandbox for this process.
460 465
461 // static 466 // static
462 bool Sandbox::EnableSandbox(SandboxProcessType sandbox_type, 467 bool Sandbox::EnableSandbox(int sandbox_type,
463 const FilePath& allowed_dir) { 468 const FilePath& allowed_dir) {
464 // Sanity - currently only SANDBOX_TYPE_UTILITY supports a directory being 469 // Sanity - currently only SANDBOX_TYPE_UTILITY supports a directory being
465 // passed in. 470 // passed in.
466 if (sandbox_type != SANDBOX_TYPE_UTILITY) { 471 if (sandbox_type < content::SANDBOX_AFTER_TYPE_LAST_TYPE &&
jeremy 2011/11/23 07:02:17 CHECK(sandbox_type < content::SANDBOX_AFTER_TYPE_L
jochen (gone - plz use gerrit) 2011/11/23 10:57:28 That's not necessarily true, as the embedder might
472 sandbox_type != content::SANDBOX_TYPE_UTILITY) {
467 DCHECK(allowed_dir.empty()) 473 DCHECK(allowed_dir.empty())
468 << "Only SANDBOX_TYPE_UTILITY allows a custom directory parameter."; 474 << "Only SANDBOX_TYPE_UTILITY allows a custom directory parameter.";
469 } 475 }
470 476
471 NSString* sandbox_data = LoadSandboxTemplate(sandbox_type); 477 NSString* sandbox_data = LoadSandboxTemplate(sandbox_type);
472 if (!sandbox_data) { 478 if (!sandbox_data) {
473 return false; 479 return false;
474 } 480 }
475 481
476 SandboxVariableSubstitions substitutions; 482 SandboxVariableSubstitions substitutions;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 if (HANDLE_EINTR(fcntl(fd, F_GETPATH, canonical_path)) != 0) { 576 if (HANDLE_EINTR(fcntl(fd, F_GETPATH, canonical_path)) != 0) {
571 DPLOG(FATAL) << "GetCanonicalSandboxPath() failed for: " 577 DPLOG(FATAL) << "GetCanonicalSandboxPath() failed for: "
572 << path->value(); 578 << path->value();
573 return; 579 return;
574 } 580 }
575 581
576 *path = FilePath(canonical_path); 582 *path = FilePath(canonical_path);
577 } 583 }
578 584
579 } // namespace sandbox 585 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698