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 |