Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <fcntl.h> | 6 #include <fcntl.h> |
| 7 #include <pthread.h> | 7 #include <pthread.h> |
| 8 #include <sys/epoll.h> | 8 #include <sys/epoll.h> |
| 9 #include <sys/prctl.h> | 9 #include <sys/prctl.h> |
| 10 #include <sys/signal.h> | 10 #include <sys/signal.h> |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 #include "base/memory/scoped_ptr.h" | 31 #include "base/memory/scoped_ptr.h" |
| 32 #include "base/path_service.h" | 32 #include "base/path_service.h" |
| 33 #include "base/pickle.h" | 33 #include "base/pickle.h" |
| 34 #include "base/process_util.h" | 34 #include "base/process_util.h" |
| 35 #include "base/rand_util.h" | 35 #include "base/rand_util.h" |
| 36 #include "base/sys_info.h" | 36 #include "base/sys_info.h" |
| 37 #include "build/build_config.h" | 37 #include "build/build_config.h" |
| 38 #include "crypto/nss_util.h" | 38 #include "crypto/nss_util.h" |
| 39 #include "chrome/common/chrome_paths.h" | 39 #include "chrome/common/chrome_paths.h" |
| 40 #include "chrome/common/chrome_switches.h" | 40 #include "chrome/common/chrome_switches.h" |
| 41 #include "chrome/nacl/nacl_helper_linux.h" | |
| 41 #include "content/common/chrome_descriptors.h" | 42 #include "content/common/chrome_descriptors.h" |
| 42 #include "content/common/font_config_ipc_linux.h" | 43 #include "content/common/font_config_ipc_linux.h" |
| 43 #include "content/common/main_function_params.h" | 44 #include "content/common/main_function_params.h" |
| 44 #include "content/common/pepper_plugin_registry.h" | 45 #include "content/common/pepper_plugin_registry.h" |
| 45 #include "content/common/process_watcher.h" | 46 #include "content/common/process_watcher.h" |
| 46 #include "content/common/result_codes.h" | 47 #include "content/common/result_codes.h" |
| 47 #include "content/common/sandbox_methods_linux.h" | 48 #include "content/common/sandbox_methods_linux.h" |
| 48 #include "content/common/set_process_title.h" | 49 #include "content/common/set_process_title.h" |
| 49 #include "content/common/unix_domain_socket_posix.h" | 50 #include "content/common/unix_domain_socket_posix.h" |
| 50 #include "media/base/media.h" | 51 #include "media/base/media.h" |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 61 | 62 |
| 62 // http://code.google.com/p/chromium/wiki/LinuxZygote | 63 // http://code.google.com/p/chromium/wiki/LinuxZygote |
| 63 | 64 |
| 64 static const int kBrowserDescriptor = 3; | 65 static const int kBrowserDescriptor = 3; |
| 65 static const int kMagicSandboxIPCDescriptor = 5; | 66 static const int kMagicSandboxIPCDescriptor = 5; |
| 66 static const int kZygoteIdDescriptor = 7; | 67 static const int kZygoteIdDescriptor = 7; |
| 67 static bool g_suid_sandbox_active = false; | 68 static bool g_suid_sandbox_active = false; |
| 68 #if defined(SECCOMP_SANDBOX) | 69 #if defined(SECCOMP_SANDBOX) |
| 69 // |g_proc_fd| is used only by the seccomp sandbox. | 70 // |g_proc_fd| is used only by the seccomp sandbox. |
| 70 static int g_proc_fd = -1; | 71 static int g_proc_fd = -1; |
| 72 static int g_nacl_helper_fd = -1; | |
| 73 static base::ProcessId g_naclpid = -1; | |
| 71 #endif | 74 #endif |
| 72 | 75 |
| 73 #if defined(CHROMIUM_SELINUX) | 76 #if defined(CHROMIUM_SELINUX) |
| 74 static void SELinuxTransitionToTypeOrDie(const char* type) { | 77 static void SELinuxTransitionToTypeOrDie(const char* type) { |
| 75 security_context_t security_context; | 78 security_context_t security_context; |
| 76 if (getcon(&security_context)) | 79 if (getcon(&security_context)) |
| 77 LOG(FATAL) << "Cannot get SELinux context"; | 80 LOG(FATAL) << "Cannot get SELinux context"; |
| 78 | 81 |
| 79 context_t context = context_new(security_context); | 82 context_t context = context_new(security_context); |
| 80 context_type_set(context, type); | 83 context_type_set(context, type); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 154 return false; | 157 return false; |
| 155 } | 158 } |
| 156 | 159 |
| 157 Pickle pickle(buf, len); | 160 Pickle pickle(buf, len); |
| 158 void* iter = NULL; | 161 void* iter = NULL; |
| 159 | 162 |
| 160 int kind; | 163 int kind; |
| 161 if (pickle.ReadInt(&iter, &kind)) { | 164 if (pickle.ReadInt(&iter, &kind)) { |
| 162 switch (kind) { | 165 switch (kind) { |
| 163 case ZygoteHost::kCmdFork: | 166 case ZygoteHost::kCmdFork: |
| 167 case ZygoteHost::kCmdNaClFork: | |
| 164 // This function call can return multiple times, once per fork(). | 168 // This function call can return multiple times, once per fork(). |
| 165 return HandleForkRequest(fd, pickle, iter, fds); | 169 return HandleForkRequest(fd, pickle, iter, fds, |
| 170 kind == ZygoteHost::kCmdNaClFork); | |
| 166 case ZygoteHost::kCmdReap: | 171 case ZygoteHost::kCmdReap: |
| 167 if (!fds.empty()) | 172 if (!fds.empty()) |
| 168 break; | 173 break; |
| 169 HandleReapRequest(fd, pickle, iter); | 174 HandleReapRequest(fd, pickle, iter); |
| 170 return false; | 175 return false; |
| 171 case ZygoteHost::kCmdGetTerminationStatus: | 176 case ZygoteHost::kCmdGetTerminationStatus: |
| 172 if (!fds.empty()) | 177 if (!fds.empty()) |
| 173 break; | 178 break; |
| 174 HandleGetTerminationStatus(fd, pickle, iter); | 179 HandleGetTerminationStatus(fd, pickle, iter); |
| 175 return false; | 180 return false; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 234 | 239 |
| 235 Pickle write_pickle; | 240 Pickle write_pickle; |
| 236 write_pickle.WriteInt(static_cast<int>(status)); | 241 write_pickle.WriteInt(static_cast<int>(status)); |
| 237 write_pickle.WriteInt(exit_code); | 242 write_pickle.WriteInt(exit_code); |
| 238 ssize_t written = | 243 ssize_t written = |
| 239 HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size())); | 244 HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size())); |
| 240 if (written != static_cast<ssize_t>(write_pickle.size())) | 245 if (written != static_cast<ssize_t>(write_pickle.size())) |
| 241 PLOG(ERROR) << "write"; | 246 PLOG(ERROR) << "write"; |
| 242 } | 247 } |
| 243 | 248 |
| 249 base::ProcessId ForkNaClLauncher(std::vector<int>& fds) { | |
| 250 base::ProcessId naclchild; | |
| 251 DLOG(INFO) << "ForkNaClLauncher"; | |
| 252 | |
| 253 if (!UnixDomainSocket::SendMsg(g_nacl_helper_fd, kNaClForkRequest, | |
| 254 sizeof(kNaClForkRequest), fds)) { | |
| 255 perror("ForkNaClLauncher: send failed"); | |
| 256 return -1; | |
| 257 } | |
| 258 if (read(g_nacl_helper_fd, &naclchild, sizeof(naclchild)) | |
| 259 != sizeof(naclchild)) { | |
| 260 perror("ForkNaClLauncher: read failed"); | |
| 261 return -1; | |
| 262 } | |
| 263 DLOG(INFO) << "nacl_child is " << naclchild; | |
| 264 return naclchild; | |
| 265 } | |
| 266 | |
| 244 // This is equivalent to fork(), except that, when using the SUID | 267 // This is equivalent to fork(), except that, when using the SUID |
| 245 // sandbox, it returns the real PID of the child process as it | 268 // sandbox, it returns the real PID of the child process as it |
| 246 // appears outside the sandbox, rather than returning the PID inside | 269 // appears outside the sandbox, rather than returning the PID inside |
| 247 // the sandbox. | 270 // the sandbox. |
| 248 int ForkWithRealPid() { | 271 int ForkWithRealPid(const bool naclfork, std::vector<int>& fds) { |
| 249 if (!g_suid_sandbox_active) | 272 // If we didn't start a nacl helper, don't use it to fork. |
| 250 return fork(); | 273 // TODO(bradchen): remove this once nacl helper is debugged |
| 274 bool isnaclfork = naclfork && (g_naclpid != -1); | |
| 275 | |
| 276 if (!g_suid_sandbox_active) { | |
| 277 DLOG(INFO) << "suid sandbox NOT active"; | |
|
agl
2011/06/10 17:28:03
This debugging should probably be removed before l
Brad Chen
2011/06/14 00:16:01
Is there a way to leave some code on longer-term f
agl
2011/06/14 14:38:36
Yes, VLOG(1) is suitable for this. See base/loggin
Brad Chen
2011/06/14 22:14:01
Done.
| |
| 278 DLOG(INFO) << "fds.size() is " << fds.size(); | |
| 279 if (isnaclfork) { | |
| 280 return ForkNaClLauncher(fds); | |
| 281 } else { | |
| 282 return fork(); | |
| 283 } | |
| 284 } | |
| 251 | 285 |
| 252 int dummy_fd; | 286 int dummy_fd; |
| 253 ino_t dummy_inode; | 287 ino_t dummy_inode; |
| 254 int pipe_fds[2] = { -1, -1 }; | 288 int pipe_fds[2] = { -1, -1 }; |
| 255 base::ProcessId pid = 0; | 289 base::ProcessId pid = 0; |
| 256 | 290 |
| 257 dummy_fd = socket(PF_UNIX, SOCK_DGRAM, 0); | 291 dummy_fd = socket(PF_UNIX, SOCK_DGRAM, 0); |
| 258 if (dummy_fd < 0) { | 292 if (dummy_fd < 0) { |
| 259 LOG(ERROR) << "Failed to create dummy FD"; | 293 LOG(ERROR) << "Failed to create dummy FD"; |
| 260 goto error; | 294 goto error; |
| 261 } | 295 } |
| 262 if (!base::FileDescriptorGetInode(&dummy_inode, dummy_fd)) { | 296 if (!base::FileDescriptorGetInode(&dummy_inode, dummy_fd)) { |
| 263 LOG(ERROR) << "Failed to get inode for dummy FD"; | 297 LOG(ERROR) << "Failed to get inode for dummy FD"; |
| 264 goto error; | 298 goto error; |
| 265 } | 299 } |
| 266 if (pipe(pipe_fds) != 0) { | 300 if (pipe(pipe_fds) != 0) { |
| 267 LOG(ERROR) << "Failed to create pipe"; | 301 LOG(ERROR) << "Failed to create pipe"; |
| 268 goto error; | 302 goto error; |
| 269 } | 303 } |
| 270 | 304 |
| 271 pid = fork(); | 305 if (isnaclfork) { |
| 306 fds.push_back(dummy_fd); | |
| 307 fds.push_back(pipe_fds[0]); | |
| 308 pid = ForkNaClLauncher(fds); | |
| 309 } else { | |
| 310 pid = fork(); | |
| 311 } | |
| 272 if (pid < 0) { | 312 if (pid < 0) { |
| 273 goto error; | 313 goto error; |
| 274 } else if (pid == 0) { | 314 } else if (pid == 0) { |
| 275 // In the child process. | 315 // In the child process. |
| 276 close(pipe_fds[1]); | 316 close(pipe_fds[1]); |
| 277 char buffer[1]; | 317 char buffer[1]; |
| 278 // Wait until the parent process has discovered our PID. We | 318 // Wait until the parent process has discovered our PID. We |
| 279 // should not fork any child processes (which the seccomp | 319 // should not fork any child processes (which the seccomp |
| 280 // sandbox does) until then, because that can interfere with the | 320 // sandbox does) until then, because that can interfere with the |
| 281 // parent's discovery of our PID. | 321 // parent's discovery of our PID. |
| 282 if (HANDLE_EINTR(read(pipe_fds[0], buffer, 1)) != 1 || | 322 if (HANDLE_EINTR(read(pipe_fds[0], buffer, 1)) != 1 || |
| 283 buffer[0] != 'x') { | 323 buffer[0] != 'x') { |
| 284 LOG(FATAL) << "Failed to synchronise with parent zygote process"; | 324 LOG(FATAL) << "Failed to synchronise with parent zygote process"; |
| 285 } | 325 } |
| 286 close(pipe_fds[0]); | 326 close(pipe_fds[0]); |
| 287 close(dummy_fd); | 327 close(dummy_fd); |
| 288 return 0; | 328 return 0; |
| 289 } else { | 329 } else { |
| 290 // In the parent process. | 330 // In the parent process. |
| 291 close(dummy_fd); | 331 close(dummy_fd); |
| 292 dummy_fd = -1; | 332 dummy_fd = -1; |
| 293 close(pipe_fds[0]); | 333 close(pipe_fds[0]); |
| 294 pipe_fds[0] = -1; | 334 pipe_fds[0] = -1; |
| 335 | |
| 295 uint8_t reply_buf[512]; | 336 uint8_t reply_buf[512]; |
| 296 Pickle request; | 337 Pickle request; |
| 297 request.WriteInt(LinuxSandbox::METHOD_GET_CHILD_WITH_INODE); | 338 request.WriteInt(LinuxSandbox::METHOD_GET_CHILD_WITH_INODE); |
| 298 request.WriteUInt64(dummy_inode); | 339 request.WriteUInt64(dummy_inode); |
| 299 | 340 |
| 300 const ssize_t r = UnixDomainSocket::SendRecvMsg( | 341 const ssize_t r = UnixDomainSocket::SendRecvMsg( |
| 301 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL, | 342 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL, |
| 302 request); | 343 request); |
| 303 if (r == -1) { | 344 if (r == -1) { |
| 304 LOG(ERROR) << "Failed to get child process's real PID"; | 345 LOG(ERROR) << "Failed to get child process's real PID"; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 334 if (pipe_fds[0] >= 0) | 375 if (pipe_fds[0] >= 0) |
| 335 close(pipe_fds[0]); | 376 close(pipe_fds[0]); |
| 336 if (pipe_fds[1] >= 0) | 377 if (pipe_fds[1] >= 0) |
| 337 close(pipe_fds[1]); | 378 close(pipe_fds[1]); |
| 338 return -1; | 379 return -1; |
| 339 } | 380 } |
| 340 | 381 |
| 341 // Handle a 'fork' request from the browser: this means that the browser | 382 // Handle a 'fork' request from the browser: this means that the browser |
| 342 // wishes to start a new renderer. | 383 // wishes to start a new renderer. |
| 343 bool HandleForkRequest(int fd, const Pickle& pickle, void* iter, | 384 bool HandleForkRequest(int fd, const Pickle& pickle, void* iter, |
| 344 std::vector<int>& fds) { | 385 std::vector<int>& fds, const bool isnaclfork) { |
| 345 std::vector<std::string> args; | 386 std::vector<std::string> args; |
| 346 int argc, numfds; | 387 int argc, numfds; |
| 347 base::GlobalDescriptors::Mapping mapping; | 388 base::GlobalDescriptors::Mapping mapping; |
| 348 base::ProcessId child; | 389 base::ProcessId child; |
| 349 | 390 |
| 350 if (!pickle.ReadInt(&iter, &argc)) | 391 if (!pickle.ReadInt(&iter, &argc)) |
| 351 goto error; | 392 goto error; |
| 352 | 393 |
| 353 for (int i = 0; i < argc; ++i) { | 394 for (int i = 0; i < argc; ++i) { |
| 354 std::string arg; | 395 std::string arg; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 365 for (int i = 0; i < numfds; ++i) { | 406 for (int i = 0; i < numfds; ++i) { |
| 366 base::GlobalDescriptors::Key key; | 407 base::GlobalDescriptors::Key key; |
| 367 if (!pickle.ReadUInt32(&iter, &key)) | 408 if (!pickle.ReadUInt32(&iter, &key)) |
| 368 goto error; | 409 goto error; |
| 369 mapping.push_back(std::make_pair(key, fds[i])); | 410 mapping.push_back(std::make_pair(key, fds[i])); |
| 370 } | 411 } |
| 371 | 412 |
| 372 mapping.push_back(std::make_pair( | 413 mapping.push_back(std::make_pair( |
| 373 static_cast<uint32_t>(kSandboxIPCChannel), kMagicSandboxIPCDescriptor)); | 414 static_cast<uint32_t>(kSandboxIPCChannel), kMagicSandboxIPCDescriptor)); |
| 374 | 415 |
| 375 child = ForkWithRealPid(); | 416 child = ForkWithRealPid(isnaclfork, fds); |
| 376 | 417 |
| 377 if (!child) { | 418 if (!child) { |
| 378 #if defined(SECCOMP_SANDBOX) | 419 #if defined(SECCOMP_SANDBOX) |
| 379 // Try to open /proc/self/maps as the seccomp sandbox needs access to it | 420 // Try to open /proc/self/maps as the seccomp sandbox needs access to it |
| 380 if (g_proc_fd >= 0) { | 421 if (g_proc_fd >= 0) { |
| 381 int proc_self_maps = openat(g_proc_fd, "self/maps", O_RDONLY); | 422 int proc_self_maps = openat(g_proc_fd, "self/maps", O_RDONLY); |
| 382 if (proc_self_maps >= 0) { | 423 if (proc_self_maps >= 0) { |
| 383 SeccompSandboxSetProcSelfMaps(proc_self_maps); | 424 SeccompSandboxSetProcSelfMaps(proc_self_maps); |
| 384 } | 425 } |
| 385 close(g_proc_fd); | 426 close(g_proc_fd); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 440 | 481 |
| 441 // In the SUID sandbox, we try to use a new PID namespace. Thus the PIDs | 482 // In the SUID sandbox, we try to use a new PID namespace. Thus the PIDs |
| 442 // fork() returns are not the real PIDs, so we need to map the Real PIDS | 483 // fork() returns are not the real PIDs, so we need to map the Real PIDS |
| 443 // into the sandbox PID namespace. | 484 // into the sandbox PID namespace. |
| 444 typedef base::hash_map<base::ProcessHandle, base::ProcessHandle> ProcessMap; | 485 typedef base::hash_map<base::ProcessHandle, base::ProcessHandle> ProcessMap; |
| 445 ProcessMap real_pids_to_sandbox_pids; | 486 ProcessMap real_pids_to_sandbox_pids; |
| 446 | 487 |
| 447 const int sandbox_flags_; | 488 const int sandbox_flags_; |
| 448 }; | 489 }; |
| 449 | 490 |
| 491 static void LaunchNaClHelper() { | |
| 492 DLOG(INFO) << "LaunchNaClHelper"; | |
|
agl
2011/06/10 17:28:03
This debugging should probably be removed before l
Brad Chen
2011/06/14 22:14:01
Replaced with VLOG(1)
On 2011/06/10 17:28:03, agl
| |
| 493 int fds[2]; | |
| 494 | |
| 495 CHECK(socketpair(PF_UNIX, SOCK_SEQPACKET, 0, fds) == 0); | |
| 496 base::file_handle_mapping_vector fds_to_map; | |
| 497 fds_to_map.push_back(std::make_pair(fds[1], 3)); | |
| 498 | |
| 499 char* nacl_zygote_exe = getenv("NACL_NEW_ZYGOTE"); | |
|
agl
2011/06/10 17:28:03
const
Brad Chen
2011/06/14 00:16:01
Done.
| |
| 500 g_naclpid = -1; | |
| 501 if (NULL != nacl_zygote_exe) { | |
| 502 CommandLine::StringVector argv = CommandLine::ForCurrentProcess()->argv(); | |
| 503 argv[0] = nacl_zygote_exe; | |
| 504 base::LaunchAppWithClone(argv, fds_to_map, false, &g_naclpid, | |
| 505 CLONE_FS | SIGCHLD); | |
| 506 } | |
| 507 close(fds[1]); | |
| 508 if (g_naclpid > 0) { | |
| 509 const int kExpectedLength = sizeof(kNaClHelperMagic); | |
| 510 char buf[kExpectedLength]; | |
| 511 int nread; | |
| 512 | |
| 513 DLOG(INFO) << "NaCl Launcher PID is " << g_naclpid; | |
|
agl
2011/06/10 17:28:03
ditto.
Brad Chen
2011/06/14 22:14:01
Replaced with VLOG(1)
On 2011/06/10 17:28:03, agl
| |
| 514 nread = read(fds[0], buf, sizeof(buf)); | |
|
agl
2011/06/10 17:28:03
nread can be declared here.
Brad Chen
2011/06/14 00:16:01
Done.
| |
| 515 DCHECK(nread == kExpectedLength) << "Incorrect NaCl helper magic length"; | |
| 516 DCHECK(0 == strcmp(buf, kNaClHelperMagic)) << "Incorrect nacl helper magic"; | |
| 517 // all is well | |
| 518 g_nacl_helper_fd = fds[0]; | |
| 519 return; | |
| 520 } | |
| 521 DLOG(INFO) << "Could not launch NaCl helper"; | |
| 522 g_naclpid = -1; | |
| 523 g_nacl_helper_fd = -1; | |
| 524 close(fds[0]); | |
| 525 | |
| 526 return; | |
| 527 } | |
| 528 | |
| 450 // With SELinux we can carve out a precise sandbox, so we don't have to play | 529 // With SELinux we can carve out a precise sandbox, so we don't have to play |
| 451 // with intercepting libc calls. | 530 // with intercepting libc calls. |
| 452 #if !defined(CHROMIUM_SELINUX) | 531 #if !defined(CHROMIUM_SELINUX) |
| 453 | 532 |
| 454 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output, | 533 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output, |
| 455 char* timezone_out, | 534 char* timezone_out, |
| 456 size_t timezone_out_len) { | 535 size_t timezone_out_len) { |
| 457 Pickle request; | 536 Pickle request; |
| 458 request.WriteInt(LinuxSandbox::METHOD_LOCALTIME); | 537 request.WriteInt(LinuxSandbox::METHOD_LOCALTIME); |
| 459 request.WriteString( | 538 request.WriteString( |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 721 if (CommandLine::ForCurrentProcess()->HasSwitch( | 800 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 722 switches::kEnableSeccompSandbox)) { | 801 switches::kEnableSeccompSandbox)) { |
| 723 g_proc_fd = open("/proc", O_DIRECTORY | O_RDONLY); | 802 g_proc_fd = open("/proc", O_DIRECTORY | O_RDONLY); |
| 724 if (g_proc_fd < 0) { | 803 if (g_proc_fd < 0) { |
| 725 LOG(ERROR) << "WARNING! Cannot access \"/proc\". Disabling seccomp " | 804 LOG(ERROR) << "WARNING! Cannot access \"/proc\". Disabling seccomp " |
| 726 "sandboxing."; | 805 "sandboxing."; |
| 727 } | 806 } |
| 728 } | 807 } |
| 729 #endif // SECCOMP_SANDBOX | 808 #endif // SECCOMP_SANDBOX |
| 730 | 809 |
| 810 // launch Native Client helper before entering the sandbox | |
| 811 LaunchNaClHelper(); | |
| 812 | |
| 731 // Turn on the SELinux or SUID sandbox | 813 // Turn on the SELinux or SUID sandbox |
| 732 if (!EnterSandbox()) { | 814 if (!EnterSandbox()) { |
| 733 LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: " | 815 LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: " |
| 734 << errno << ")"; | 816 << errno << ")"; |
| 735 return false; | 817 return false; |
| 736 } | 818 } |
| 737 | 819 |
| 738 int sandbox_flags = 0; | 820 int sandbox_flags = 0; |
| 739 if (getenv("SBX_D")) | 821 if (getenv("SBX_D")) |
| 740 sandbox_flags |= ZygoteHost::kSandboxSUID; | 822 sandbox_flags |= ZygoteHost::kSandboxSUID; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 761 VLOG(1) << "Enabling experimental Seccomp sandbox."; | 843 VLOG(1) << "Enabling experimental Seccomp sandbox."; |
| 762 sandbox_flags |= ZygoteHost::kSandboxSeccomp; | 844 sandbox_flags |= ZygoteHost::kSandboxSeccomp; |
| 763 } | 845 } |
| 764 } | 846 } |
| 765 #endif // SECCOMP_SANDBOX | 847 #endif // SECCOMP_SANDBOX |
| 766 | 848 |
| 767 Zygote zygote(sandbox_flags); | 849 Zygote zygote(sandbox_flags); |
| 768 // This function call can return multiple times, once per fork(). | 850 // This function call can return multiple times, once per fork(). |
| 769 return zygote.ProcessRequests(); | 851 return zygote.ProcessRequests(); |
| 770 } | 852 } |
| OLD | NEW |