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 |