| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 | 13 |
| 14 #include "base/basictypes.h" | 14 #include "base/basictypes.h" |
| 15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 16 #include "base/file_util.h" | 16 #include "base/file_util.h" |
| 17 #include "base/mac_util.h" | 17 #include "base/mac_util.h" |
| 18 #include "base/rand_util_c.h" |
| 18 #include "base/scoped_cftyperef.h" | 19 #include "base/scoped_cftyperef.h" |
| 19 #include "base/scoped_nsautorelease_pool.h" | 20 #include "base/scoped_nsautorelease_pool.h" |
| 20 #include "base/string16.h" | 21 #include "base/string16.h" |
| 21 #include "base/sys_info.h" | 22 #include "base/sys_info.h" |
| 22 #include "base/sys_string_conversions.h" | 23 #include "base/sys_string_conversions.h" |
| 23 #include "base/utf_string_conversions.h" | 24 #include "base/utf_string_conversions.h" |
| 24 #include "chrome/common/chrome_switches.h" | 25 #include "chrome/common/chrome_switches.h" |
| 25 #include "unicode/uchar.h" | 26 #include "unicode/uchar.h" |
| 26 | 27 |
| 27 namespace { | 28 namespace { |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 { // CGImageSourceGetStatus() - 10.6 | 228 { // CGImageSourceGetStatus() - 10.6 |
| 228 // Create a png with just enough data to get everything warmed up... | 229 // Create a png with just enough data to get everything warmed up... |
| 229 char png_header[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}; | 230 char png_header[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}; |
| 230 NSData* data = [NSData dataWithBytes:png_header | 231 NSData* data = [NSData dataWithBytes:png_header |
| 231 length:arraysize(png_header)]; | 232 length:arraysize(png_header)]; |
| 232 scoped_cftyperef<CGImageSourceRef> img( | 233 scoped_cftyperef<CGImageSourceRef> img( |
| 233 CGImageSourceCreateWithData((CFDataRef)data, | 234 CGImageSourceCreateWithData((CFDataRef)data, |
| 234 NULL)); | 235 NULL)); |
| 235 CGImageSourceGetStatus(img); | 236 CGImageSourceGetStatus(img); |
| 236 } | 237 } |
| 238 |
| 239 { // Native Client access to /dev/random. |
| 240 GetUrandomFD(); |
| 241 } |
| 237 } | 242 } |
| 238 | 243 |
| 239 // Turns on the OS X sandbox for this process. | 244 // Turns on the OS X sandbox for this process. |
| 240 bool EnableSandbox(SandboxProcessType sandbox_type, | 245 bool EnableSandbox(SandboxProcessType sandbox_type, |
| 241 const FilePath& allowed_dir) { | 246 const FilePath& allowed_dir) { |
| 242 // Sanity - currently only SANDBOX_TYPE_UTILITY supports a directory being | 247 // Sanity - currently only SANDBOX_TYPE_UTILITY supports a directory being |
| 243 // passed in. | 248 // passed in. |
| 244 if (sandbox_type != SANDBOX_TYPE_UTILITY) { | 249 if (sandbox_type != SANDBOX_TYPE_UTILITY) { |
| 245 DCHECK(allowed_dir.empty()) | 250 DCHECK(allowed_dir.empty()) |
| 246 << "Only SANDBOX_TYPE_UTILITY allows a custom directory parameter."; | 251 << "Only SANDBOX_TYPE_UTILITY allows a custom directory parameter."; |
| 247 } | 252 } |
| 248 // We use a custom sandbox definition file to lock things down as | 253 // We use a custom sandbox definition file to lock things down as |
| 249 // tightly as possible. | 254 // tightly as possible. |
| 250 // TODO(jeremy): Look at using include syntax to unify common parts of sandbox | 255 // TODO(jeremy): Look at using include syntax to unify common parts of sandbox |
| 251 // definition files. | 256 // definition files. |
| 252 NSString* sandbox_config_filename = nil; | 257 NSString* sandbox_config_filename = nil; |
| 258 bool allow_nacl_lines = false; |
| 253 switch (sandbox_type) { | 259 switch (sandbox_type) { |
| 254 case SANDBOX_TYPE_RENDERER: | 260 case SANDBOX_TYPE_RENDERER: |
| 255 sandbox_config_filename = @"renderer"; | 261 sandbox_config_filename = @"renderer"; |
| 256 break; | 262 break; |
| 257 case SANDBOX_TYPE_WORKER: | 263 case SANDBOX_TYPE_WORKER: |
| 258 sandbox_config_filename = @"worker"; | 264 sandbox_config_filename = @"worker"; |
| 259 break; | 265 break; |
| 260 case SANDBOX_TYPE_UTILITY: | 266 case SANDBOX_TYPE_UTILITY: |
| 261 sandbox_config_filename = @"utility"; | 267 sandbox_config_filename = @"utility"; |
| 262 break; | 268 break; |
| 269 case SANDBOX_TYPE_NACL_PLUGIN: |
| 270 // The Native Client plugin is a standard renderer sandbox with some |
| 271 // additional lines to support use of Unix sockets. |
| 272 // TODO(msneck): Remove the use of Unix sockets from Native Client and |
| 273 // then remove the associated rules from chrome/renderer/renderer.sb. |
| 274 // See http://code.google.com/p/nativeclient/issues/detail?id=344 |
| 275 sandbox_config_filename = @"renderer"; |
| 276 allow_nacl_lines = true; |
| 277 break; |
| 278 case SANDBOX_TYPE_NACL_LOADER: |
| 279 // The Native Client loader is used for safeguarding the user's |
| 280 // untrusted code within Native Client. |
| 281 // TODO(msneck): Remove the use of Unix sockets from Native Client and |
| 282 // then decide on an appropriate sandbox type for the untrusted code. |
| 283 // This might simply mean removing the Unix socket rules from |
| 284 // chrome/browser/nacl-loader.sb or it might mean sharing the |
| 285 // sandbox configuration with SANDBOX_TYPE_WORKER. |
| 286 // See http://code.google.com/p/nativeclient/issues/detail?id=344 |
| 287 sandbox_config_filename = @"nacl-loader"; |
| 288 break; |
| 263 default: | 289 default: |
| 264 NOTREACHED(); | 290 NOTREACHED(); |
| 265 return false; | 291 return false; |
| 266 } | 292 } |
| 267 | 293 |
| 268 NSString* sandbox_profile_path = | 294 NSString* sandbox_profile_path = |
| 269 [mac_util::MainAppBundle() pathForResource:sandbox_config_filename | 295 [mac_util::MainAppBundle() pathForResource:sandbox_config_filename |
| 270 ofType:@"sb"]; | 296 ofType:@"sb"]; |
| 271 NSString* sandbox_data = [NSString | 297 NSString* sandbox_data = [NSString |
| 272 stringWithContentsOfFile:sandbox_profile_path | 298 stringWithContentsOfFile:sandbox_profile_path |
| 273 encoding:NSUTF8StringEncoding | 299 encoding:NSUTF8StringEncoding |
| 274 error:nil]; | 300 error:nil]; |
| 275 | 301 |
| 276 if (!sandbox_data) { | 302 if (!sandbox_data) { |
| 277 PLOG(ERROR) << "Failed to find the sandbox profile on disk " | 303 PLOG(ERROR) << "Failed to find the sandbox profile on disk " |
| 278 << base::SysNSStringToUTF8(sandbox_profile_path); | 304 << base::SysNSStringToUTF8(sandbox_profile_path); |
| 279 return false; | 305 return false; |
| 280 } | 306 } |
| 281 | 307 |
| 282 // Enable verbose logging if enabled on the command line. | 308 // Enable verbose logging if enabled on the command line. |
| 283 // (see renderer.sb for details). | 309 // (see renderer.sb for details). |
| 284 const CommandLine *command_line = CommandLine::ForCurrentProcess(); | 310 const CommandLine *command_line = CommandLine::ForCurrentProcess(); |
| 285 if (command_line->HasSwitch(switches::kEnableSandboxLogging)) { | 311 if (command_line->HasSwitch(switches::kEnableSandboxLogging)) { |
| 286 sandbox_data = [sandbox_data | 312 sandbox_data = [sandbox_data |
| 287 stringByReplacingOccurrencesOfString:@";ENABLE_LOGGING" | 313 stringByReplacingOccurrencesOfString:@";ENABLE_LOGGING" |
| 288 withString:@""]; | 314 withString:@""]; |
| 289 } | 315 } |
| 290 | 316 |
| 317 // Enable Native Client lines if they are allowed. |
| 318 if (allow_nacl_lines) { |
| 319 sandbox_data = [sandbox_data |
| 320 stringByReplacingOccurrencesOfString:@";NACL" |
| 321 withString:@""]; |
| 322 } |
| 323 |
| 291 if (!allowed_dir.empty()) { | 324 if (!allowed_dir.empty()) { |
| 292 // The sandbox only understands "real" paths. This resolving step is | 325 // The sandbox only understands "real" paths. This resolving step is |
| 293 // needed so the caller doesn't need to worry about things like /var | 326 // needed so the caller doesn't need to worry about things like /var |
| 294 // being a link to /private/var (like in the paths CreateNewTempDirectory() | 327 // being a link to /private/var (like in the paths CreateNewTempDirectory() |
| 295 // returns). | 328 // returns). |
| 296 FilePath allowed_dir_absolute(allowed_dir); | 329 FilePath allowed_dir_absolute(allowed_dir); |
| 297 if (!file_util::AbsolutePath(&allowed_dir_absolute)) { | 330 if (!file_util::AbsolutePath(&allowed_dir_absolute)) { |
| 298 PLOG(ERROR) << "Failed to resolve absolute path"; | 331 PLOG(ERROR) << "Failed to resolve absolute path"; |
| 299 return false; | 332 return false; |
| 300 } | 333 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 std::string home_dir = base::SysNSStringToUTF8(NSHomeDirectory()); | 367 std::string home_dir = base::SysNSStringToUTF8(NSHomeDirectory()); |
| 335 std::string home_dir_escaped; | 368 std::string home_dir_escaped; |
| 336 if (!QuotePlainString(home_dir, &home_dir_escaped)) { | 369 if (!QuotePlainString(home_dir, &home_dir_escaped)) { |
| 337 LOG(ERROR) << "Sandbox string quoting failed"; | 370 LOG(ERROR) << "Sandbox string quoting failed"; |
| 338 return false; | 371 return false; |
| 339 } | 372 } |
| 340 NSString* home_dir_escaped_ns = base::SysUTF8ToNSString(home_dir_escaped); | 373 NSString* home_dir_escaped_ns = base::SysUTF8ToNSString(home_dir_escaped); |
| 341 sandbox_data = [sandbox_data | 374 sandbox_data = [sandbox_data |
| 342 stringByReplacingOccurrencesOfString:@"USER_HOMEDIR" | 375 stringByReplacingOccurrencesOfString:@"USER_HOMEDIR" |
| 343 withString:home_dir_escaped_ns]; | 376 withString:home_dir_escaped_ns]; |
| 377 } else if (major_version == 10 && minor_version < 6) { |
| 378 // Sandbox rules only for versions before 10.6. |
| 379 sandbox_data = [sandbox_data |
| 380 stringByReplacingOccurrencesOfString:@";BEFORE_10.6" |
| 381 withString:@""]; |
| 344 } | 382 } |
| 345 | 383 |
| 346 char* error_buff = NULL; | 384 char* error_buff = NULL; |
| 347 int error = sandbox_init([sandbox_data UTF8String], 0, &error_buff); | 385 int error = sandbox_init([sandbox_data UTF8String], 0, &error_buff); |
| 348 bool success = (error == 0 && error_buff == NULL); | 386 bool success = (error == 0 && error_buff == NULL); |
| 349 LOG_IF(ERROR, !success) << "Failed to initialize sandbox: " | 387 LOG_IF(ERROR, !success) << "Failed to initialize sandbox: " |
| 350 << error | 388 << error |
| 351 << " " | 389 << " " |
| 352 << error_buff; | 390 << error_buff; |
| 353 sandbox_free_error(error_buff); | 391 sandbox_free_error(error_buff); |
| 354 return success; | 392 return success; |
| 355 } | 393 } |
| 356 | 394 |
| 357 } // namespace sandbox | 395 } // namespace sandbox |
| OLD | NEW |