OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/zygote/zygote_main.h" | 5 #include "content/zygote/zygote_main.h" |
6 | 6 |
7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <pthread.h> | 9 #include <pthread.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 #include <sys/prctl.h> | 48 #include <sys/prctl.h> |
49 #include <sys/signal.h> | 49 #include <sys/signal.h> |
50 #else | 50 #else |
51 #include <signal.h> | 51 #include <signal.h> |
52 #endif | 52 #endif |
53 | 53 |
54 namespace content { | 54 namespace content { |
55 | 55 |
56 // See http://code.google.com/p/chromium/wiki/LinuxZygote | 56 // See http://code.google.com/p/chromium/wiki/LinuxZygote |
57 | 57 |
58 // With SELinux we can carve out a precise sandbox, so we don't have to play | |
59 // with intercepting libc calls. | |
60 #if !defined(CHROMIUM_SELINUX) | |
61 | |
62 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output, | 58 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output, |
63 char* timezone_out, | 59 char* timezone_out, |
64 size_t timezone_out_len) { | 60 size_t timezone_out_len) { |
65 Pickle request; | 61 Pickle request; |
66 request.WriteInt(LinuxSandbox::METHOD_LOCALTIME); | 62 request.WriteInt(LinuxSandbox::METHOD_LOCALTIME); |
67 request.WriteString( | 63 request.WriteString( |
68 std::string(reinterpret_cast<char*>(&input), sizeof(input))); | 64 std::string(reinterpret_cast<char*>(&input), sizeof(input))); |
69 | 65 |
70 uint8_t reply_buf[512]; | 66 uint8_t reply_buf[512]; |
71 const ssize_t r = UnixDomainSocket::SendRecvMsg( | 67 const ssize_t r = UnixDomainSocket::SendRecvMsg( |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 if (g_am_zygote_or_renderer) { | 239 if (g_am_zygote_or_renderer) { |
244 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); | 240 ProxyLocaltimeCallToBrowser(*timep, result, NULL, 0); |
245 return result; | 241 return result; |
246 } else { | 242 } else { |
247 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, | 243 CHECK_EQ(0, pthread_once(&g_libc_localtime_funcs_guard, |
248 InitLibcLocaltimeFunctions)); | 244 InitLibcLocaltimeFunctions)); |
249 return g_libc_localtime64_r(timep, result); | 245 return g_libc_localtime64_r(timep, result); |
250 } | 246 } |
251 } | 247 } |
252 | 248 |
253 #endif // !CHROMIUM_SELINUX | |
254 | |
255 // This function triggers the static and lazy construction of objects that need | 249 // This function triggers the static and lazy construction of objects that need |
256 // to be created before imposing the sandbox. | 250 // to be created before imposing the sandbox. |
257 static void PreSandboxInit() { | 251 static void PreSandboxInit() { |
258 base::RandUint64(); | 252 base::RandUint64(); |
259 | 253 |
260 base::SysInfo::MaxSharedMemorySize(); | 254 base::SysInfo::MaxSharedMemorySize(); |
261 | 255 |
262 // ICU DateFormat class (used in base/time_format.cc) needs to get the | 256 // ICU DateFormat class (used in base/time_format.cc) needs to get the |
263 // Olson timezone ID by accessing the zoneinfo files on disk. After | 257 // Olson timezone ID by accessing the zoneinfo files on disk. After |
264 // TimeZone::createDefault is called once here, the timezone ID is | 258 // TimeZone::createDefault is called once here, the timezone ID is |
(...skipping 15 matching lines...) Expand all Loading... |
280 #endif | 274 #endif |
281 #if defined(ENABLE_PLUGINS) | 275 #if defined(ENABLE_PLUGINS) |
282 // Ensure access to the Pepper plugins before the sandbox is turned on. | 276 // Ensure access to the Pepper plugins before the sandbox is turned on. |
283 PepperPluginRegistry::PreloadModules(); | 277 PepperPluginRegistry::PreloadModules(); |
284 #endif | 278 #endif |
285 #if defined(ENABLE_WEBRTC) | 279 #if defined(ENABLE_WEBRTC) |
286 InitializeWebRtcModule(); | 280 InitializeWebRtcModule(); |
287 #endif | 281 #endif |
288 } | 282 } |
289 | 283 |
290 #if !defined(CHROMIUM_SELINUX) | |
291 // Do nothing here | 284 // Do nothing here |
292 static void SIGCHLDHandler(int signal) { | 285 static void SIGCHLDHandler(int signal) { |
293 } | 286 } |
294 | 287 |
295 // The current process will become a process reaper like init. | 288 // The current process will become a process reaper like init. |
296 // We fork a child that will continue normally, when it dies, we can safely | 289 // We fork a child that will continue normally, when it dies, we can safely |
297 // exit. | 290 // exit. |
298 // We need to be careful we close the magic kZygoteIdFd properly in the parent | 291 // We need to be careful we close the magic kZygoteIdFd properly in the parent |
299 // before this function returns. | 292 // before this function returns. |
300 static bool CreateInitProcessReaper() { | 293 static bool CreateInitProcessReaper() { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) { | 419 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)) { |
427 LOG(ERROR) << "Failed to set non-dumpable flag"; | 420 LOG(ERROR) << "Failed to set non-dumpable flag"; |
428 return false; | 421 return false; |
429 } | 422 } |
430 } | 423 } |
431 #endif | 424 #endif |
432 } | 425 } |
433 | 426 |
434 return true; | 427 return true; |
435 } | 428 } |
436 #else // CHROMIUM_SELINUX | |
437 | |
438 static bool EnterSandbox(sandbox::SetuidSandboxClient* setuid_sandbox, | |
439 bool* using_suid_sandbox, bool* has_started_new_init) { | |
440 *using_suid_sandbox = false; | |
441 *has_started_new_init = false; | |
442 | |
443 if (!setuid_sandbox) | |
444 return false; | |
445 | |
446 PreSandboxInit(); | |
447 SkFontConfigInterface::SetGlobal( | |
448 new FontConfigIPC(Zygote::kMagicSandboxIPCDescriptor))->unref(); | |
449 return true; | |
450 } | |
451 | |
452 #endif // CHROMIUM_SELINUX | |
453 | 429 |
454 bool ZygoteMain(const MainFunctionParams& params, | 430 bool ZygoteMain(const MainFunctionParams& params, |
455 ZygoteForkDelegate* forkdelegate) { | 431 ZygoteForkDelegate* forkdelegate) { |
456 #if !defined(CHROMIUM_SELINUX) | |
457 g_am_zygote_or_renderer = true; | 432 g_am_zygote_or_renderer = true; |
458 sandbox::InitLibcUrandomOverrides(); | 433 sandbox::InitLibcUrandomOverrides(); |
459 #endif | |
460 | 434 |
461 LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance(); | 435 LinuxSandbox* linux_sandbox = LinuxSandbox::GetInstance(); |
462 // This will pre-initialize the various sandboxes that need it. | 436 // This will pre-initialize the various sandboxes that need it. |
463 linux_sandbox->PreinitializeSandbox(); | 437 linux_sandbox->PreinitializeSandbox(); |
464 | 438 |
465 sandbox::SetuidSandboxClient* setuid_sandbox = | 439 sandbox::SetuidSandboxClient* setuid_sandbox = |
466 linux_sandbox->setuid_sandbox_client(); | 440 linux_sandbox->setuid_sandbox_client(); |
467 | 441 |
468 if (forkdelegate != NULL) { | 442 if (forkdelegate != NULL) { |
469 VLOG(1) << "ZygoteMain: initializing fork delegate"; | 443 VLOG(1) << "ZygoteMain: initializing fork delegate"; |
470 forkdelegate->Init(Zygote::kMagicSandboxIPCDescriptor); | 444 forkdelegate->Init(Zygote::kMagicSandboxIPCDescriptor); |
471 } else { | 445 } else { |
472 VLOG(1) << "ZygoteMain: fork delegate is NULL"; | 446 VLOG(1) << "ZygoteMain: fork delegate is NULL"; |
473 } | 447 } |
474 | 448 |
475 // Turn on the SELinux or SUID sandbox. | 449 // Turn on the sandbox. |
476 bool using_suid_sandbox = false; | 450 bool using_suid_sandbox = false; |
477 bool has_started_new_init = false; | 451 bool has_started_new_init = false; |
478 | 452 |
479 if (!EnterSandbox(setuid_sandbox, | 453 if (!EnterSandbox(setuid_sandbox, |
480 &using_suid_sandbox, | 454 &using_suid_sandbox, |
481 &has_started_new_init)) { | 455 &has_started_new_init)) { |
482 LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: " | 456 LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: " |
483 << errno << ")"; | 457 << errno << ")"; |
484 return false; | 458 return false; |
485 } | 459 } |
486 | 460 |
487 if (setuid_sandbox->IsInNewPIDNamespace() && !has_started_new_init) { | 461 if (setuid_sandbox->IsInNewPIDNamespace() && !has_started_new_init) { |
488 LOG(ERROR) << "The SUID sandbox created a new PID namespace but Zygote " | 462 LOG(ERROR) << "The SUID sandbox created a new PID namespace but Zygote " |
489 "is not the init process. Please, make sure the SUID " | 463 "is not the init process. Please, make sure the SUID " |
490 "binary is up to date."; | 464 "binary is up to date."; |
491 } | 465 } |
492 | 466 |
493 int sandbox_flags = linux_sandbox->GetStatus(); | 467 int sandbox_flags = linux_sandbox->GetStatus(); |
494 | 468 |
495 Zygote zygote(sandbox_flags, forkdelegate); | 469 Zygote zygote(sandbox_flags, forkdelegate); |
496 // This function call can return multiple times, once per fork(). | 470 // This function call can return multiple times, once per fork(). |
497 return zygote.ProcessRequests(); | 471 return zygote.ProcessRequests(); |
498 } | 472 } |
499 | 473 |
500 } // namespace content | 474 } // namespace content |
OLD | NEW |