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 "content/browser/zygote_host_linux.h" | 5 #include "content/browser/zygote_host_linux.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 <sys/socket.h> | 10 #include <sys/socket.h> |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include "content/common/chrome_descriptors.h" | 30 #include "content/common/chrome_descriptors.h" |
31 #include "content/common/content_switches.h" | 31 #include "content/common/content_switches.h" |
32 #include "content/common/font_config_ipc_linux.h" | 32 #include "content/common/font_config_ipc_linux.h" |
33 #include "content/common/main_function_params.h" | 33 #include "content/common/main_function_params.h" |
34 #include "content/common/pepper_plugin_registry.h" | 34 #include "content/common/pepper_plugin_registry.h" |
35 #include "content/common/process_watcher.h" | 35 #include "content/common/process_watcher.h" |
36 #include "content/common/result_codes.h" | 36 #include "content/common/result_codes.h" |
37 #include "content/common/sandbox_methods_linux.h" | 37 #include "content/common/sandbox_methods_linux.h" |
38 #include "content/common/set_process_title.h" | 38 #include "content/common/set_process_title.h" |
39 #include "content/common/unix_domain_socket_posix.h" | 39 #include "content/common/unix_domain_socket_posix.h" |
40 #include "content/common/zygote_fork_delegate_linux.h" | |
41 #include "seccompsandbox/sandbox.h" | 40 #include "seccompsandbox/sandbox.h" |
42 #include "skia/ext/SkFontHost_fontconfig_control.h" | 41 #include "skia/ext/SkFontHost_fontconfig_control.h" |
43 #include "unicode/timezone.h" | 42 #include "unicode/timezone.h" |
44 #include "ipc/ipc_switches.h" | |
45 | 43 |
46 #if defined(OS_LINUX) | 44 #if defined(OS_LINUX) |
47 #include <sys/epoll.h> | 45 #include <sys/epoll.h> |
48 #include <sys/prctl.h> | 46 #include <sys/prctl.h> |
49 #include <sys/signal.h> | 47 #include <sys/signal.h> |
50 #else | 48 #else |
51 #include <signal.h> | 49 #include <signal.h> |
52 #endif | 50 #endif |
53 | 51 |
54 #if defined(CHROMIUM_SELINUX) | 52 #if defined(CHROMIUM_SELINUX) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 "the policies haven't been loaded into the kernel?)"; | 90 "the policies haven't been loaded into the kernel?)"; |
93 } | 91 } |
94 } | 92 } |
95 #endif // CHROMIUM_SELINUX | 93 #endif // CHROMIUM_SELINUX |
96 | 94 |
97 // This is the object which implements the zygote. The ZygoteMain function, | 95 // This is the object which implements the zygote. The ZygoteMain function, |
98 // which is called from ChromeMain, simply constructs one of these objects and | 96 // which is called from ChromeMain, simply constructs one of these objects and |
99 // runs it. | 97 // runs it. |
100 class Zygote { | 98 class Zygote { |
101 public: | 99 public: |
102 explicit Zygote(int sandbox_flags, ZygoteForkDelegate& helper) | 100 explicit Zygote(int sandbox_flags) |
103 : sandbox_flags_(sandbox_flags), | 101 : sandbox_flags_(sandbox_flags) { |
104 helper_(helper) { | |
105 } | 102 } |
106 | 103 |
107 bool ProcessRequests() { | 104 bool ProcessRequests() { |
108 // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the | 105 // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the |
109 // browser on it. | 106 // browser on it. |
110 // A SOCK_DGRAM is installed in fd 5. This is the sandbox IPC channel. | 107 // A SOCK_DGRAM is installed in fd 5. This is the sandbox IPC channel. |
111 // See http://code.google.com/p/chromium/wiki/LinuxSandboxIPC | 108 // See http://code.google.com/p/chromium/wiki/LinuxSandboxIPC |
112 | 109 |
113 // We need to accept SIGCHLD, even though our handler is a no-op because | 110 // We need to accept SIGCHLD, even though our handler is a no-op because |
114 // otherwise we cannot wait on children. (According to POSIX 2001.) | 111 // otherwise we cannot wait on children. (According to POSIX 2001.) |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 | 158 |
162 Pickle pickle(buf, len); | 159 Pickle pickle(buf, len); |
163 void* iter = NULL; | 160 void* iter = NULL; |
164 | 161 |
165 int kind; | 162 int kind; |
166 if (pickle.ReadInt(&iter, &kind)) { | 163 if (pickle.ReadInt(&iter, &kind)) { |
167 switch (kind) { | 164 switch (kind) { |
168 case ZygoteHost::kCmdFork: | 165 case ZygoteHost::kCmdFork: |
169 // This function call can return multiple times, once per fork(). | 166 // This function call can return multiple times, once per fork(). |
170 return HandleForkRequest(fd, pickle, iter, fds); | 167 return HandleForkRequest(fd, pickle, iter, fds); |
171 | |
172 case ZygoteHost::kCmdReap: | 168 case ZygoteHost::kCmdReap: |
173 if (!fds.empty()) | 169 if (!fds.empty()) |
174 break; | 170 break; |
175 HandleReapRequest(fd, pickle, iter); | 171 HandleReapRequest(fd, pickle, iter); |
176 return false; | 172 return false; |
177 case ZygoteHost::kCmdGetTerminationStatus: | 173 case ZygoteHost::kCmdGetTerminationStatus: |
178 if (!fds.empty()) | 174 if (!fds.empty()) |
179 break; | 175 break; |
180 HandleGetTerminationStatus(fd, pickle, iter); | 176 HandleGetTerminationStatus(fd, pickle, iter); |
181 return false; | 177 return false; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 ssize_t written = | 240 ssize_t written = |
245 HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size())); | 241 HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size())); |
246 if (written != static_cast<ssize_t>(write_pickle.size())) | 242 if (written != static_cast<ssize_t>(write_pickle.size())) |
247 PLOG(ERROR) << "write"; | 243 PLOG(ERROR) << "write"; |
248 } | 244 } |
249 | 245 |
250 // This is equivalent to fork(), except that, when using the SUID | 246 // This is equivalent to fork(), except that, when using the SUID |
251 // sandbox, it returns the real PID of the child process as it | 247 // sandbox, it returns the real PID of the child process as it |
252 // appears outside the sandbox, rather than returning the PID inside | 248 // appears outside the sandbox, rather than returning the PID inside |
253 // the sandbox. | 249 // the sandbox. |
254 int ForkWithRealPid(const std::string& process_type, std::vector<int>& fds, | 250 int ForkWithRealPid() { |
255 const std::string& channel_switch) { | 251 if (!g_suid_sandbox_active) |
256 const bool use_helper = helper_.CanHelp(process_type); | |
257 if (!(use_helper || g_suid_sandbox_active)) { | |
258 return fork(); | 252 return fork(); |
259 } | |
260 | 253 |
261 int dummy_fd; | 254 int dummy_fd; |
262 ino_t dummy_inode; | 255 ino_t dummy_inode; |
263 int pipe_fds[2] = { -1, -1 }; | 256 int pipe_fds[2] = { -1, -1 }; |
264 base::ProcessId pid = 0; | 257 base::ProcessId pid = 0; |
265 | 258 |
266 dummy_fd = socket(PF_UNIX, SOCK_DGRAM, 0); | 259 dummy_fd = socket(PF_UNIX, SOCK_DGRAM, 0); |
267 if (dummy_fd < 0) { | 260 if (dummy_fd < 0) { |
268 LOG(ERROR) << "Failed to create dummy FD"; | 261 LOG(ERROR) << "Failed to create dummy FD"; |
269 goto error; | 262 goto error; |
270 } | 263 } |
271 if (!base::FileDescriptorGetInode(&dummy_inode, dummy_fd)) { | 264 if (!base::FileDescriptorGetInode(&dummy_inode, dummy_fd)) { |
272 LOG(ERROR) << "Failed to get inode for dummy FD"; | 265 LOG(ERROR) << "Failed to get inode for dummy FD"; |
273 goto error; | 266 goto error; |
274 } | 267 } |
275 if (pipe(pipe_fds) != 0) { | 268 if (pipe(pipe_fds) != 0) { |
276 LOG(ERROR) << "Failed to create pipe"; | 269 LOG(ERROR) << "Failed to create pipe"; |
277 goto error; | 270 goto error; |
278 } | 271 } |
279 | 272 |
280 if (use_helper) { | 273 pid = fork(); |
281 fds.push_back(dummy_fd); | |
282 fds.push_back(pipe_fds[0]); | |
283 pid = helper_.Fork(fds); | |
284 } else { | |
285 pid = fork(); | |
286 } | |
287 if (pid < 0) { | 274 if (pid < 0) { |
288 goto error; | 275 goto error; |
289 } else if (pid == 0) { | 276 } else if (pid == 0) { |
290 // In the child process. | 277 // In the child process. |
291 close(pipe_fds[1]); | 278 close(pipe_fds[1]); |
292 char buffer[1]; | 279 char buffer[1]; |
293 // Wait until the parent process has discovered our PID. We | 280 // Wait until the parent process has discovered our PID. We |
294 // should not fork any child processes (which the seccomp | 281 // should not fork any child processes (which the seccomp |
295 // sandbox does) until then, because that can interfere with the | 282 // sandbox does) until then, because that can interfere with the |
296 // parent's discovery of our PID. | 283 // parent's discovery of our PID. |
297 if (HANDLE_EINTR(read(pipe_fds[0], buffer, 1)) != 1 || | 284 if (HANDLE_EINTR(read(pipe_fds[0], buffer, 1)) != 1 || |
298 buffer[0] != 'x') { | 285 buffer[0] != 'x') { |
299 LOG(FATAL) << "Failed to synchronise with parent zygote process"; | 286 LOG(FATAL) << "Failed to synchronise with parent zygote process"; |
300 } | 287 } |
301 close(pipe_fds[0]); | 288 close(pipe_fds[0]); |
302 close(dummy_fd); | 289 close(dummy_fd); |
303 return 0; | 290 return 0; |
304 } else { | 291 } else { |
305 // In the parent process. | 292 // In the parent process. |
306 close(dummy_fd); | 293 close(dummy_fd); |
307 dummy_fd = -1; | 294 dummy_fd = -1; |
308 close(pipe_fds[0]); | 295 close(pipe_fds[0]); |
309 pipe_fds[0] = -1; | 296 pipe_fds[0] = -1; |
| 297 uint8_t reply_buf[512]; |
| 298 Pickle request; |
| 299 request.WriteInt(LinuxSandbox::METHOD_GET_CHILD_WITH_INODE); |
| 300 request.WriteUInt64(dummy_inode); |
| 301 |
| 302 const ssize_t r = UnixDomainSocket::SendRecvMsg( |
| 303 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL, |
| 304 request); |
| 305 if (r == -1) { |
| 306 LOG(ERROR) << "Failed to get child process's real PID"; |
| 307 goto error; |
| 308 } |
| 309 |
310 base::ProcessId real_pid; | 310 base::ProcessId real_pid; |
311 if (g_suid_sandbox_active) { | 311 Pickle reply(reinterpret_cast<char*>(reply_buf), r); |
312 uint8_t reply_buf[512]; | 312 void* iter2 = NULL; |
313 Pickle request; | 313 if (!reply.ReadInt(&iter2, &real_pid)) |
314 request.WriteInt(LinuxSandbox::METHOD_GET_CHILD_WITH_INODE); | 314 goto error; |
315 request.WriteUInt64(dummy_inode); | 315 if (real_pid <= 0) { |
316 | 316 // METHOD_GET_CHILD_WITH_INODE failed. Did the child die already? |
317 const ssize_t r = UnixDomainSocket::SendRecvMsg( | 317 LOG(ERROR) << "METHOD_GET_CHILD_WITH_INODE failed"; |
318 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL, | 318 goto error; |
319 request); | |
320 if (r == -1) { | |
321 LOG(ERROR) << "Failed to get child process's real PID"; | |
322 goto error; | |
323 } | |
324 | |
325 Pickle reply(reinterpret_cast<char*>(reply_buf), r); | |
326 void* iter = NULL; | |
327 if (!reply.ReadInt(&iter, &real_pid)) | |
328 goto error; | |
329 if (real_pid <= 0) { | |
330 // METHOD_GET_CHILD_WITH_INODE failed. Did the child die already? | |
331 LOG(ERROR) << "METHOD_GET_CHILD_WITH_INODE failed"; | |
332 goto error; | |
333 } | |
334 real_pids_to_sandbox_pids[real_pid] = pid; | |
335 } | 319 } |
336 if (use_helper) { | 320 real_pids_to_sandbox_pids[real_pid] = pid; |
337 real_pid = pid; | 321 if (HANDLE_EINTR(write(pipe_fds[1], "x", 1)) != 1) { |
338 if (!helper_.AckChild(pipe_fds[1], channel_switch)) { | 322 LOG(ERROR) << "Failed to synchronise with child process"; |
339 LOG(ERROR) << "Failed to synchronise with NaCl child process"; | 323 goto error; |
340 goto error; | |
341 } | |
342 } else { | |
343 if (HANDLE_EINTR(write(pipe_fds[1], "x", 1)) != 1) { | |
344 LOG(ERROR) << "Failed to synchronise with child process"; | |
345 goto error; | |
346 } | |
347 } | 324 } |
348 close(pipe_fds[1]); | 325 close(pipe_fds[1]); |
349 return real_pid; | 326 return real_pid; |
350 } | 327 } |
351 | 328 |
352 error: | 329 error: |
353 if (pid > 0) { | 330 if (pid > 0) { |
354 if (waitpid(pid, NULL, WNOHANG) == -1) | 331 if (waitpid(pid, NULL, WNOHANG) == -1) |
355 LOG(ERROR) << "Failed to wait for process"; | 332 LOG(ERROR) << "Failed to wait for process"; |
356 } | 333 } |
357 if (dummy_fd >= 0) | 334 if (dummy_fd >= 0) |
358 close(dummy_fd); | 335 close(dummy_fd); |
359 if (pipe_fds[0] >= 0) | 336 if (pipe_fds[0] >= 0) |
360 close(pipe_fds[0]); | 337 close(pipe_fds[0]); |
361 if (pipe_fds[1] >= 0) | 338 if (pipe_fds[1] >= 0) |
362 close(pipe_fds[1]); | 339 close(pipe_fds[1]); |
363 return -1; | 340 return -1; |
364 } | 341 } |
365 | 342 |
366 // Handle a 'fork' request from the browser: this means that the browser | 343 // Handle a 'fork' request from the browser: this means that the browser |
367 // wishes to start a new renderer. | 344 // wishes to start a new renderer. |
368 bool HandleForkRequest(int fd, const Pickle& pickle, | 345 bool HandleForkRequest(int fd, const Pickle& pickle, void* iter, |
369 void* iter, std::vector<int>& fds) { | 346 std::vector<int>& fds) { |
370 std::vector<std::string> args; | 347 std::vector<std::string> args; |
371 int argc, numfds; | 348 int argc, numfds; |
372 base::GlobalDescriptors::Mapping mapping; | 349 base::GlobalDescriptors::Mapping mapping; |
373 base::ProcessId child; | 350 base::ProcessId child; |
374 std::string process_type; | |
375 std::string channel_id; | |
376 const std::string channel_id_prefix = std::string("--") | |
377 + switches::kProcessChannelID + std::string("="); | |
378 | |
379 if (!pickle.ReadString(&iter, &process_type)) | |
380 goto error; | |
381 | 351 |
382 if (!pickle.ReadInt(&iter, &argc)) | 352 if (!pickle.ReadInt(&iter, &argc)) |
383 goto error; | 353 goto error; |
384 | 354 |
385 for (int i = 0; i < argc; ++i) { | 355 for (int i = 0; i < argc; ++i) { |
386 std::string arg; | 356 std::string arg; |
387 if (!pickle.ReadString(&iter, &arg)) | 357 if (!pickle.ReadString(&iter, &arg)) |
388 goto error; | 358 goto error; |
389 args.push_back(arg); | 359 args.push_back(arg); |
390 if (arg.compare(0, channel_id_prefix.length(), channel_id_prefix) == 0) | |
391 channel_id = arg; | |
392 } | 360 } |
393 | 361 |
394 if (!pickle.ReadInt(&iter, &numfds)) | 362 if (!pickle.ReadInt(&iter, &numfds)) |
395 goto error; | 363 goto error; |
396 if (numfds != static_cast<int>(fds.size())) | 364 if (numfds != static_cast<int>(fds.size())) |
397 goto error; | 365 goto error; |
398 | 366 |
399 for (int i = 0; i < numfds; ++i) { | 367 for (int i = 0; i < numfds; ++i) { |
400 base::GlobalDescriptors::Key key; | 368 base::GlobalDescriptors::Key key; |
401 if (!pickle.ReadUInt32(&iter, &key)) | 369 if (!pickle.ReadUInt32(&iter, &key)) |
402 goto error; | 370 goto error; |
403 mapping.push_back(std::make_pair(key, fds[i])); | 371 mapping.push_back(std::make_pair(key, fds[i])); |
404 } | 372 } |
405 | 373 |
406 mapping.push_back(std::make_pair( | 374 mapping.push_back(std::make_pair( |
407 static_cast<uint32_t>(kSandboxIPCChannel), kMagicSandboxIPCDescriptor)); | 375 static_cast<uint32_t>(kSandboxIPCChannel), kMagicSandboxIPCDescriptor)); |
408 | 376 |
409 child = ForkWithRealPid(process_type, fds, channel_id); | 377 child = ForkWithRealPid(); |
410 | 378 |
411 if (!child) { | 379 if (!child) { |
412 #if defined(SECCOMP_SANDBOX) | 380 #if defined(SECCOMP_SANDBOX) |
413 // Try to open /proc/self/maps as the seccomp sandbox needs access to it | 381 // Try to open /proc/self/maps as the seccomp sandbox needs access to it |
414 if (g_proc_fd >= 0) { | 382 if (g_proc_fd >= 0) { |
415 int proc_self_maps = openat(g_proc_fd, "self/maps", O_RDONLY); | 383 int proc_self_maps = openat(g_proc_fd, "self/maps", O_RDONLY); |
416 if (proc_self_maps >= 0) { | 384 if (proc_self_maps >= 0) { |
417 SeccompSandboxSetProcSelfMaps(proc_self_maps); | 385 SeccompSandboxSetProcSelfMaps(proc_self_maps); |
418 } | 386 } |
419 close(g_proc_fd); | 387 close(g_proc_fd); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 return false; | 440 return false; |
473 } | 441 } |
474 | 442 |
475 // In the SUID sandbox, we try to use a new PID namespace. Thus the PIDs | 443 // In the SUID sandbox, we try to use a new PID namespace. Thus the PIDs |
476 // fork() returns are not the real PIDs, so we need to map the Real PIDS | 444 // fork() returns are not the real PIDs, so we need to map the Real PIDS |
477 // into the sandbox PID namespace. | 445 // into the sandbox PID namespace. |
478 typedef base::hash_map<base::ProcessHandle, base::ProcessHandle> ProcessMap; | 446 typedef base::hash_map<base::ProcessHandle, base::ProcessHandle> ProcessMap; |
479 ProcessMap real_pids_to_sandbox_pids; | 447 ProcessMap real_pids_to_sandbox_pids; |
480 | 448 |
481 const int sandbox_flags_; | 449 const int sandbox_flags_; |
482 ZygoteForkDelegate& helper_; | |
483 }; | 450 }; |
484 | 451 |
485 // With SELinux we can carve out a precise sandbox, so we don't have to play | 452 // With SELinux we can carve out a precise sandbox, so we don't have to play |
486 // with intercepting libc calls. | 453 // with intercepting libc calls. |
487 #if !defined(CHROMIUM_SELINUX) | 454 #if !defined(CHROMIUM_SELINUX) |
488 | 455 |
489 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output, | 456 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output, |
490 char* timezone_out, | 457 char* timezone_out, |
491 size_t timezone_out_len) { | 458 size_t timezone_out_len) { |
492 Pickle request; | 459 Pickle request; |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 #else // CHROMIUM_SELINUX | 698 #else // CHROMIUM_SELINUX |
732 | 699 |
733 static bool EnterSandbox() { | 700 static bool EnterSandbox() { |
734 PreSandboxInit(); | 701 PreSandboxInit(); |
735 SkiaFontConfigUseIPCImplementation(kMagicSandboxIPCDescriptor); | 702 SkiaFontConfigUseIPCImplementation(kMagicSandboxIPCDescriptor); |
736 return true; | 703 return true; |
737 } | 704 } |
738 | 705 |
739 #endif // CHROMIUM_SELINUX | 706 #endif // CHROMIUM_SELINUX |
740 | 707 |
741 bool ZygoteMain(const MainFunctionParams& params, | 708 bool ZygoteMain(const MainFunctionParams& params) { |
742 const ZygoteForkDelegate& forkdelegate) { | |
743 #if !defined(CHROMIUM_SELINUX) | 709 #if !defined(CHROMIUM_SELINUX) |
744 g_am_zygote_or_renderer = true; | 710 g_am_zygote_or_renderer = true; |
745 #endif | 711 #endif |
746 | 712 |
747 #if defined(SECCOMP_SANDBOX) | 713 #if defined(SECCOMP_SANDBOX) |
748 // The seccomp sandbox needs access to files in /proc, which might be denied | 714 // The seccomp sandbox needs access to files in /proc, which might be denied |
749 // after one of the other sandboxes have been started. So, obtain a suitable | 715 // after one of the other sandboxes have been started. So, obtain a suitable |
750 // file handle in advance. | 716 // file handle in advance. |
751 if (CommandLine::ForCurrentProcess()->HasSwitch( | 717 if (CommandLine::ForCurrentProcess()->HasSwitch( |
752 switches::kEnableSeccompSandbox)) { | 718 switches::kEnableSeccompSandbox)) { |
753 g_proc_fd = open("/proc", O_DIRECTORY | O_RDONLY); | 719 g_proc_fd = open("/proc", O_DIRECTORY | O_RDONLY); |
754 if (g_proc_fd < 0) { | 720 if (g_proc_fd < 0) { |
755 LOG(ERROR) << "WARNING! Cannot access \"/proc\". Disabling seccomp " | 721 LOG(ERROR) << "WARNING! Cannot access \"/proc\". Disabling seccomp " |
756 "sandboxing."; | 722 "sandboxing."; |
757 } | 723 } |
758 } | 724 } |
759 #endif // SECCOMP_SANDBOX | 725 #endif // SECCOMP_SANDBOX |
760 | 726 |
761 VLOG(1) << "initializing fork delegate"; | |
762 forkdelegate.Init(getenv("SBX_D") != NULL, // g_suid_sandbox_active, | |
763 kBrowserDescriptor, kMagicSandboxIPCDescriptor); | |
764 | |
765 // Turn on the SELinux or SUID sandbox | 727 // Turn on the SELinux or SUID sandbox |
766 if (!EnterSandbox()) { | 728 if (!EnterSandbox()) { |
767 LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: " | 729 LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: " |
768 << errno << ")"; | 730 << errno << ")"; |
769 return false; | 731 return false; |
770 } | 732 } |
771 | 733 |
772 int sandbox_flags = 0; | 734 int sandbox_flags = 0; |
773 if (getenv("SBX_D")) | 735 if (getenv("SBX_D")) |
774 sandbox_flags |= ZygoteHost::kSandboxSUID; | 736 sandbox_flags |= ZygoteHost::kSandboxSUID; |
(...skipping 16 matching lines...) Expand all Loading... |
791 LOG(ERROR) << "WARNING! This machine lacks support needed for the " | 753 LOG(ERROR) << "WARNING! This machine lacks support needed for the " |
792 "Seccomp sandbox. Running renderers with Seccomp " | 754 "Seccomp sandbox. Running renderers with Seccomp " |
793 "sandboxing disabled."; | 755 "sandboxing disabled."; |
794 } else { | 756 } else { |
795 VLOG(1) << "Enabling experimental Seccomp sandbox."; | 757 VLOG(1) << "Enabling experimental Seccomp sandbox."; |
796 sandbox_flags |= ZygoteHost::kSandboxSeccomp; | 758 sandbox_flags |= ZygoteHost::kSandboxSeccomp; |
797 } | 759 } |
798 } | 760 } |
799 #endif // SECCOMP_SANDBOX | 761 #endif // SECCOMP_SANDBOX |
800 | 762 |
801 Zygote zygote(sandbox_flags, forkdelegate); | 763 Zygote zygote(sandbox_flags); |
802 // This function call can return multiple times, once per fork(). | 764 // This function call can return multiple times, once per fork(). |
803 return zygote.ProcessRequests(); | 765 return zygote.ProcessRequests(); |
804 } | 766 } |
OLD | NEW |