Chromium Code Reviews| 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 <dlfcn.h> | 5 #include <dlfcn.h> |
| 6 #include <unistd.h> | 6 #include <unistd.h> |
| 7 #include <sys/epoll.h> | 7 #include <sys/epoll.h> |
| 8 #include <sys/types.h> | 8 #include <sys/types.h> |
| 9 #include <sys/socket.h> | 9 #include <sys/socket.h> |
| 10 #include <sys/signal.h> | 10 #include <sys/signal.h> |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 #include "chrome/common/chrome_descriptors.h" | 25 #include "chrome/common/chrome_descriptors.h" |
| 26 #include "chrome/common/chrome_switches.h" | 26 #include "chrome/common/chrome_switches.h" |
| 27 #include "chrome/common/main_function_params.h" | 27 #include "chrome/common/main_function_params.h" |
| 28 #include "chrome/common/process_watcher.h" | 28 #include "chrome/common/process_watcher.h" |
| 29 #include "chrome/common/sandbox_methods_linux.h" | 29 #include "chrome/common/sandbox_methods_linux.h" |
| 30 | 30 |
| 31 #include "media/base/media.h" | 31 #include "media/base/media.h" |
| 32 | 32 |
| 33 #include "skia/ext/SkFontHost_fontconfig_control.h" | 33 #include "skia/ext/SkFontHost_fontconfig_control.h" |
| 34 | 34 |
| 35 #if defined(CHROMIUM_SELINUX) | |
| 36 #include <selinux/selinux.h> | |
| 37 #include <selinux/context.h> | |
| 38 #endif | |
| 39 | |
| 35 // http://code.google.com/p/chromium/wiki/LinuxZygote | 40 // http://code.google.com/p/chromium/wiki/LinuxZygote |
| 36 | 41 |
| 37 static const int kMagicSandboxIPCDescriptor = 5; | 42 static const int kMagicSandboxIPCDescriptor = 5; |
| 38 | 43 |
| 39 // This is the object which implements the zygote. The ZygoteMain function, | 44 // This is the object which implements the zygote. The ZygoteMain function, |
| 40 // which is called from ChromeMain, at the the bottom and simple constructs one | 45 // which is called from ChromeMain, at the the bottom and simple constructs one |
| 41 // of these objects and runs it. | 46 // of these objects and runs it. |
| 42 class Zygote { | 47 class Zygote { |
| 43 public: | 48 public: |
| 44 bool ProcessRequests() { | 49 bool ProcessRequests() { |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 200 | 205 |
| 201 error: | 206 error: |
| 202 LOG(WARNING) << "Error parsing fork request from browser"; | 207 LOG(WARNING) << "Error parsing fork request from browser"; |
| 203 for (std::vector<int>::const_iterator | 208 for (std::vector<int>::const_iterator |
| 204 i = fds.begin(); i != fds.end(); ++i) | 209 i = fds.begin(); i != fds.end(); ++i) |
| 205 close(*i); | 210 close(*i); |
| 206 return false; | 211 return false; |
| 207 } | 212 } |
| 208 }; | 213 }; |
| 209 | 214 |
| 215 // With SELinux we can carve out a precise sandbox, so we don't have to play | |
| 216 // with intercepting libc calls. | |
| 217 #ifndef CHROMIUM_SELINUX | |
|
Evan Martin
2009/09/15 18:45:51
if !defined(
| |
| 218 | |
| 210 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output, | 219 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output, |
| 211 char* timezone_out, | 220 char* timezone_out, |
| 212 size_t timezone_out_len) { | 221 size_t timezone_out_len) { |
| 213 Pickle request; | 222 Pickle request; |
| 214 request.WriteInt(LinuxSandbox::METHOD_LOCALTIME); | 223 request.WriteInt(LinuxSandbox::METHOD_LOCALTIME); |
| 215 request.WriteString( | 224 request.WriteString( |
| 216 std::string(reinterpret_cast<char*>(&input), sizeof(input))); | 225 std::string(reinterpret_cast<char*>(&input), sizeof(input))); |
| 217 | 226 |
| 218 uint8_t reply_buf[512]; | 227 uint8_t reply_buf[512]; |
| 219 const ssize_t r = base::SendRecvMsg( | 228 const ssize_t r = base::SendRecvMsg( |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 344 static void WarnOnceAboutBrokenDlsym() { | 353 static void WarnOnceAboutBrokenDlsym() { |
| 345 static bool have_shown_warning = false; | 354 static bool have_shown_warning = false; |
| 346 if (!have_shown_warning) { | 355 if (!have_shown_warning) { |
| 347 LOG(ERROR) << "Your system is broken: dlsym doesn't work! This has been " | 356 LOG(ERROR) << "Your system is broken: dlsym doesn't work! This has been " |
| 348 "reported to be caused by Nvidia's libGL. You should expect " | 357 "reported to be caused by Nvidia's libGL. You should expect " |
| 349 "time related functions to misbehave. " | 358 "time related functions to misbehave. " |
| 350 "http://code.google.com/p/chromium/issues/detail?id=16800"; | 359 "http://code.google.com/p/chromium/issues/detail?id=16800"; |
| 351 have_shown_warning = true; | 360 have_shown_warning = true; |
| 352 } | 361 } |
| 353 } | 362 } |
| 363 #endif // !CHROMIUM_SELINUX | |
| 354 | 364 |
| 355 static bool MaybeEnterChroot() { | 365 // This function trigger the static and lazy construction of objects that need |
|
Evan Martin
2009/09/15 18:45:51
triggers
| |
| 356 const char* const sandbox_fd_string = getenv("SBX_D"); | 366 // to be created before imposing the sandbox. |
| 357 if (sandbox_fd_string) { | 367 static void PreSandboxInit() { |
| 358 // The SUID sandbox sets this environment variable to a file descriptor | |
| 359 // over which we can signal that we have completed our startup and can be | |
| 360 // chrooted. | |
| 361 | |
| 362 char* endptr; | |
| 363 const long fd_long = strtol(sandbox_fd_string, &endptr, 10); | |
| 364 if (!*sandbox_fd_string || *endptr || fd_long < 0 || fd_long > INT_MAX) | |
| 365 return false; | |
| 366 const int fd = fd_long; | |
| 367 | |
| 368 // Before entering the sandbox, "prime" any systems that need to open | |
| 369 // files and cache the results or the descriptors. | |
| 370 base::RandUint64(); | 368 base::RandUint64(); |
| 371 | 369 |
| 372 base::SysInfo::MaxSharedMemorySize(); | 370 base::SysInfo::MaxSharedMemorySize(); |
| 373 | 371 |
| 374 // To make wcstombs/mbstowcs work in a renderer, setlocale() has to be | 372 // To make wcstombs/mbstowcs work in a renderer, setlocale() has to be |
| 375 // called before the sandbox is triggered. It's possible to avoid calling | 373 // called before the sandbox is triggered. It's possible to avoid calling |
| 376 // setlocale() by pulling out the conversion between FilePath and | 374 // setlocale() by pulling out the conversion between FilePath and |
| 377 // WebCore String out of the renderer and using string16 in place of | 375 // WebCore String out of the renderer and using string16 in place of |
| 378 // FilePath for IPC. | 376 // FilePath for IPC. |
| 379 const char* locale = setlocale(LC_ALL, ""); | 377 const char* locale = setlocale(LC_ALL, ""); |
| 380 LOG_IF(WARNING, locale == NULL) << "setlocale failed."; | 378 LOG_IF(WARNING, locale == NULL) << "setlocale failed."; |
| 381 | 379 |
| 382 FilePath module_path; | 380 FilePath module_path; |
| 383 if (PathService::Get(base::DIR_MODULE, &module_path)) | 381 if (PathService::Get(base::DIR_MODULE, &module_path)) |
| 384 media::InitializeMediaLibrary(module_path); | 382 media::InitializeMediaLibrary(module_path); |
| 383 } | |
| 384 | |
| 385 #if !defined(CHROMIUM_SELINUX) | |
| 386 static bool EnterSandbox() { | |
| 387 const char* const sandbox_fd_string = getenv("SBX_D"); | |
| 388 if (sandbox_fd_string) { | |
| 389 // The SUID sandbox sets this environment variable to a file descriptor | |
| 390 // over which we can signal that we have completed our startup and can be | |
| 391 // chrooted. | |
| 392 | |
| 393 char* endptr; | |
| 394 const long fd_long = strtol(sandbox_fd_string, &endptr, 10); | |
| 395 if (!*sandbox_fd_string || *endptr || fd_long < 0 || fd_long > INT_MAX) | |
| 396 return false; | |
| 397 const int fd = fd_long; | |
| 398 | |
| 399 PreSandboxInit(); | |
| 385 | 400 |
| 386 static const char kChrootMe = 'C'; | 401 static const char kChrootMe = 'C'; |
| 387 static const char kChrootMeSuccess = 'O'; | 402 static const char kChrootMeSuccess = 'O'; |
| 388 | 403 |
| 389 if (HANDLE_EINTR(write(fd, &kChrootMe, 1)) != 1) { | 404 if (HANDLE_EINTR(write(fd, &kChrootMe, 1)) != 1) { |
| 390 LOG(ERROR) << "Failed to write to chroot pipe: " << errno; | 405 LOG(ERROR) << "Failed to write to chroot pipe: " << errno; |
| 391 return false; | 406 return false; |
| 392 } | 407 } |
| 393 | 408 |
| 394 // We need to reap the chroot helper process in any event: | 409 // We need to reap the chroot helper process in any event: |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 431 LOG(ERROR) << "Failed to set non-dumpable flag"; | 446 LOG(ERROR) << "Failed to set non-dumpable flag"; |
| 432 return false; | 447 return false; |
| 433 } | 448 } |
| 434 } | 449 } |
| 435 } else { | 450 } else { |
| 436 SkiaFontConfigUseDirectImplementation(); | 451 SkiaFontConfigUseDirectImplementation(); |
| 437 } | 452 } |
| 438 | 453 |
| 439 return true; | 454 return true; |
| 440 } | 455 } |
| 456 #else // !CHROMIUM_SELINUX | |
|
Evan Martin
2009/09/15 18:45:51
it might be less confusing to remove the ! here, s
| |
| 457 | |
| 458 static bool EnterSandbox() { | |
| 459 PreSandboxInit(); | |
| 460 SkiaFontConfigUseIPCImplementation(kMagicSandboxIPCDescriptor); | |
| 461 | |
| 462 security_context_t security_context; | |
| 463 if (getcon(&security_context)) { | |
| 464 LOG(ERROR) << "Cannot get SELinux context"; | |
| 465 return false; | |
| 466 } | |
| 467 | |
| 468 context_t context = context_new(security_context); | |
| 469 context_type_set(context, "chromium_renderer_t"); | |
| 470 const int r = setcon(context_str(context)); | |
| 471 context_free(context); | |
| 472 freecon(security_context); | |
| 473 | |
| 474 if (r) { | |
| 475 LOG(ERROR) << "dyntrans failed to type 'chromium_renderer_t'"; | |
|
Evan Martin
2009/09/15 18:45:51
Is dyntrans a term selinux people would understand
| |
| 476 return false; | |
| 477 } | |
| 478 | |
| 479 return true; | |
| 480 } | |
| 441 | 481 |
| 482 #endif // CHROMIUM_SELINUX | |
| 483 | |
| 442 bool ZygoteMain(const MainFunctionParams& params) { | 484 bool ZygoteMain(const MainFunctionParams& params) { |
| 485 #if !defined(CHROMIUM_SELINUX) | |
|
Evan Martin
2009/09/15 18:45:51
why is this necessary?
| |
| 443 g_am_zygote_or_renderer = true; | 486 g_am_zygote_or_renderer = true; |
| 487 #endif | |
| 444 | 488 |
| 445 if (!MaybeEnterChroot()) { | 489 if (!EnterSandbox()) { |
| 446 LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: " | 490 LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: " |
| 447 << errno << ")"; | 491 << errno << ")"; |
| 448 return false; | 492 return false; |
| 449 } | 493 } |
| 450 | 494 |
| 451 Zygote zygote; | 495 Zygote zygote; |
| 452 return zygote.ProcessRequests(); | 496 return zygote.ProcessRequests(); |
| 453 } | 497 } |
| OLD | NEW |