Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(214)

Side by Side Diff: content/browser/zygote_main_linux.cc

Issue 6995121: New NaCl zygote implementation 2 (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Follow #define conventions Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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"
40 #include "seccompsandbox/sandbox.h" 41 #include "seccompsandbox/sandbox.h"
41 #include "skia/ext/SkFontHost_fontconfig_control.h" 42 #include "skia/ext/SkFontHost_fontconfig_control.h"
42 #include "unicode/timezone.h" 43 #include "unicode/timezone.h"
44 #include "ipc/ipc_switches.h"
43 45
44 #if defined(OS_LINUX) 46 #if defined(OS_LINUX)
45 #include <sys/epoll.h> 47 #include <sys/epoll.h>
46 #include <sys/prctl.h> 48 #include <sys/prctl.h>
47 #include <sys/signal.h> 49 #include <sys/signal.h>
48 #else 50 #else
49 #include <signal.h> 51 #include <signal.h>
50 #endif 52 #endif
51 53
52 #if defined(CHROMIUM_SELINUX) 54 #if defined(CHROMIUM_SELINUX)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 freecon(security_context); 87 freecon(security_context);
86 88
87 if (r) { 89 if (r) {
88 LOG(FATAL) << "dynamic transition to type '" << type << "' failed. " 90 LOG(FATAL) << "dynamic transition to type '" << type << "' failed. "
89 "(this binary has been built with SELinux support, but maybe " 91 "(this binary has been built with SELinux support, but maybe "
90 "the policies haven't been loaded into the kernel?)"; 92 "the policies haven't been loaded into the kernel?)";
91 } 93 }
92 } 94 }
93 #endif // CHROMIUM_SELINUX 95 #endif // CHROMIUM_SELINUX
94 96
97 static std::string ExtractArg(std::vector<std::string> args,
Evan Martin 2011/06/24 18:57:33 Use namespace{} instead of static Why no comments
Brad Chen 2011/06/25 22:14:51 Comments added. Given the consistent use of "stat
98 const std::string swtch) {
Evan Martin 2011/06/24 18:57:33 Pass by reference, not by copying
Brad Chen 2011/06/25 22:14:51 Done.
99 const std::string key = "--" + swtch + "=";
100 int len = key.length();
101 for (size_t i = 0; i < args.size(); i++) {
102 if (key.compare(0, len, args[i], 0, len) == 0) {
103 return args[i];
104 }
105 }
106 return "";
107 }
108
95 // This is the object which implements the zygote. The ZygoteMain function, 109 // This is the object which implements the zygote. The ZygoteMain function,
96 // which is called from ChromeMain, simply constructs one of these objects and 110 // which is called from ChromeMain, simply constructs one of these objects and
97 // runs it. 111 // runs it.
98 class Zygote { 112 class Zygote {
99 public: 113 public:
100 explicit Zygote(int sandbox_flags) 114 explicit Zygote(int sandbox_flags, ZygoteForkDelegate* helper)
101 : sandbox_flags_(sandbox_flags) { 115 : sandbox_flags_(sandbox_flags),
116 helper_(helper) {
102 } 117 }
103 118
104 bool ProcessRequests() { 119 bool ProcessRequests() {
105 // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the 120 // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the
106 // browser on it. 121 // browser on it.
107 // A SOCK_DGRAM is installed in fd 5. This is the sandbox IPC channel. 122 // A SOCK_DGRAM is installed in fd 5. This is the sandbox IPC channel.
108 // See http://code.google.com/p/chromium/wiki/LinuxSandboxIPC 123 // See http://code.google.com/p/chromium/wiki/LinuxSandboxIPC
109 124
110 // We need to accept SIGCHLD, even though our handler is a no-op because 125 // We need to accept SIGCHLD, even though our handler is a no-op because
111 // otherwise we cannot wait on children. (According to POSIX 2001.) 126 // otherwise we cannot wait on children. (According to POSIX 2001.)
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 168
154 if (len == -1) { 169 if (len == -1) {
155 PLOG(ERROR) << "Error reading message from browser"; 170 PLOG(ERROR) << "Error reading message from browser";
156 return false; 171 return false;
157 } 172 }
158 173
159 Pickle pickle(buf, len); 174 Pickle pickle(buf, len);
160 void* iter = NULL; 175 void* iter = NULL;
161 176
162 int kind; 177 int kind;
178 std::string process_type;
163 if (pickle.ReadInt(&iter, &kind)) { 179 if (pickle.ReadInt(&iter, &kind)) {
164 switch (kind) { 180 switch (kind) {
165 case ZygoteHost::kCmdFork: 181 case ZygoteHost::kCmdFork:
166 // This function call can return multiple times, once per fork(). 182 // This function call can return multiple times, once per fork().
167 return HandleForkRequest(fd, pickle, iter, fds); 183 pickle.ReadString(&iter, &process_type);
184 return HandleForkRequest(fd, pickle, iter, fds, process_type);
Evan Martin 2011/06/24 18:57:33 Since HandleForkRequest reaches into the pickle an
Brad Chen 2011/06/25 22:14:51 Done.
185
168 case ZygoteHost::kCmdReap: 186 case ZygoteHost::kCmdReap:
169 if (!fds.empty()) 187 if (!fds.empty())
170 break; 188 break;
171 HandleReapRequest(fd, pickle, iter); 189 HandleReapRequest(fd, pickle, iter);
172 return false; 190 return false;
173 case ZygoteHost::kCmdGetTerminationStatus: 191 case ZygoteHost::kCmdGetTerminationStatus:
174 if (!fds.empty()) 192 if (!fds.empty())
175 break; 193 break;
176 HandleGetTerminationStatus(fd, pickle, iter); 194 HandleGetTerminationStatus(fd, pickle, iter);
177 return false; 195 return false;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 ssize_t written = 258 ssize_t written =
241 HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size())); 259 HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size()));
242 if (written != static_cast<ssize_t>(write_pickle.size())) 260 if (written != static_cast<ssize_t>(write_pickle.size()))
243 PLOG(ERROR) << "write"; 261 PLOG(ERROR) << "write";
244 } 262 }
245 263
246 // This is equivalent to fork(), except that, when using the SUID 264 // This is equivalent to fork(), except that, when using the SUID
247 // sandbox, it returns the real PID of the child process as it 265 // sandbox, it returns the real PID of the child process as it
248 // appears outside the sandbox, rather than returning the PID inside 266 // appears outside the sandbox, rather than returning the PID inside
249 // the sandbox. 267 // the sandbox.
250 int ForkWithRealPid() { 268 int ForkWithRealPid(const std::string process_type, std::vector<int>& fds,
251 if (!g_suid_sandbox_active) 269 const std::string channel_switch) {
270 const bool use_helper = (helper_ && helper_->CanHelp(process_type));
271 if (!(use_helper || g_suid_sandbox_active)) {
252 return fork(); 272 return fork();
273 }
253 274
254 int dummy_fd; 275 int dummy_fd;
255 ino_t dummy_inode; 276 ino_t dummy_inode;
256 int pipe_fds[2] = { -1, -1 }; 277 int pipe_fds[2] = { -1, -1 };
257 base::ProcessId pid = 0; 278 base::ProcessId pid = 0;
258 279
259 dummy_fd = socket(PF_UNIX, SOCK_DGRAM, 0); 280 dummy_fd = socket(PF_UNIX, SOCK_DGRAM, 0);
260 if (dummy_fd < 0) { 281 if (dummy_fd < 0) {
261 LOG(ERROR) << "Failed to create dummy FD"; 282 LOG(ERROR) << "Failed to create dummy FD";
262 goto error; 283 goto error;
263 } 284 }
264 if (!base::FileDescriptorGetInode(&dummy_inode, dummy_fd)) { 285 if (!base::FileDescriptorGetInode(&dummy_inode, dummy_fd)) {
265 LOG(ERROR) << "Failed to get inode for dummy FD"; 286 LOG(ERROR) << "Failed to get inode for dummy FD";
266 goto error; 287 goto error;
267 } 288 }
268 if (pipe(pipe_fds) != 0) { 289 if (pipe(pipe_fds) != 0) {
269 LOG(ERROR) << "Failed to create pipe"; 290 LOG(ERROR) << "Failed to create pipe";
270 goto error; 291 goto error;
271 } 292 }
272 293
273 pid = fork(); 294 if (use_helper) {
295 fds.push_back(dummy_fd);
296 fds.push_back(pipe_fds[0]);
297 pid = helper_->Fork(fds);
298 } else {
299 pid = fork();
300 }
274 if (pid < 0) { 301 if (pid < 0) {
275 goto error; 302 goto error;
276 } else if (pid == 0) { 303 } else if (pid == 0) {
277 // In the child process. 304 // In the child process.
278 close(pipe_fds[1]); 305 close(pipe_fds[1]);
279 char buffer[1]; 306 char buffer[1];
280 // Wait until the parent process has discovered our PID. We 307 // Wait until the parent process has discovered our PID. We
281 // should not fork any child processes (which the seccomp 308 // should not fork any child processes (which the seccomp
282 // sandbox does) until then, because that can interfere with the 309 // sandbox does) until then, because that can interfere with the
283 // parent's discovery of our PID. 310 // parent's discovery of our PID.
284 if (HANDLE_EINTR(read(pipe_fds[0], buffer, 1)) != 1 || 311 if (HANDLE_EINTR(read(pipe_fds[0], buffer, 1)) != 1 ||
285 buffer[0] != 'x') { 312 buffer[0] != 'x') {
286 LOG(FATAL) << "Failed to synchronise with parent zygote process"; 313 LOG(FATAL) << "Failed to synchronise with parent zygote process";
287 } 314 }
288 close(pipe_fds[0]); 315 close(pipe_fds[0]);
289 close(dummy_fd); 316 close(dummy_fd);
290 return 0; 317 return 0;
291 } else { 318 } else {
292 // In the parent process. 319 // In the parent process.
293 close(dummy_fd); 320 close(dummy_fd);
294 dummy_fd = -1; 321 dummy_fd = -1;
295 close(pipe_fds[0]); 322 close(pipe_fds[0]);
296 pipe_fds[0] = -1; 323 pipe_fds[0] = -1;
297 uint8_t reply_buf[512]; 324 base::ProcessId real_pid;
298 Pickle request; 325 if (g_suid_sandbox_active) {
299 request.WriteInt(LinuxSandbox::METHOD_GET_CHILD_WITH_INODE); 326 uint8_t reply_buf[512];
300 request.WriteUInt64(dummy_inode); 327 Pickle request;
328 request.WriteInt(LinuxSandbox::METHOD_GET_CHILD_WITH_INODE);
329 request.WriteUInt64(dummy_inode);
301 330
302 const ssize_t r = UnixDomainSocket::SendRecvMsg( 331 const ssize_t r = UnixDomainSocket::SendRecvMsg(
303 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL, 332 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL,
304 request); 333 request);
305 if (r == -1) { 334 if (r == -1) {
306 LOG(ERROR) << "Failed to get child process's real PID"; 335 LOG(ERROR) << "Failed to get child process's real PID";
307 goto error; 336 goto error;
337 }
338
339 Pickle reply(reinterpret_cast<char*>(reply_buf), r);
340 void* iter2 = NULL;
341 if (!reply.ReadInt(&iter2, &real_pid))
342 goto error;
343 if (real_pid <= 0) {
344 // METHOD_GET_CHILD_WITH_INODE failed. Did the child die already?
345 LOG(ERROR) << "METHOD_GET_CHILD_WITH_INODE failed";
346 goto error;
347 }
348 real_pids_to_sandbox_pids[real_pid] = pid;
308 } 349 }
309 350 if (use_helper) {
310 base::ProcessId real_pid; 351 real_pid = pid;
311 Pickle reply(reinterpret_cast<char*>(reply_buf), r); 352 if (!helper_->AckChild(pipe_fds[1], channel_switch)) {
312 void* iter2 = NULL; 353 LOG(ERROR) << "Failed to synchronise with NaCl child process";
313 if (!reply.ReadInt(&iter2, &real_pid)) 354 goto error;
314 goto error; 355 }
315 if (real_pid <= 0) { 356 } else {
316 // METHOD_GET_CHILD_WITH_INODE failed. Did the child die already? 357 if (HANDLE_EINTR(write(pipe_fds[1], "x", 1)) != 1) {
317 LOG(ERROR) << "METHOD_GET_CHILD_WITH_INODE failed"; 358 LOG(ERROR) << "Failed to synchronise with child process";
318 goto error; 359 goto error;
319 } 360 }
320 real_pids_to_sandbox_pids[real_pid] = pid;
321 if (HANDLE_EINTR(write(pipe_fds[1], "x", 1)) != 1) {
322 LOG(ERROR) << "Failed to synchronise with child process";
323 goto error;
324 } 361 }
325 close(pipe_fds[1]); 362 close(pipe_fds[1]);
326 return real_pid; 363 return real_pid;
327 } 364 }
328 365
329 error: 366 error:
330 if (pid > 0) { 367 if (pid > 0) {
331 if (waitpid(pid, NULL, WNOHANG) == -1) 368 if (waitpid(pid, NULL, WNOHANG) == -1)
332 LOG(ERROR) << "Failed to wait for process"; 369 LOG(ERROR) << "Failed to wait for process";
333 } 370 }
334 if (dummy_fd >= 0) 371 if (dummy_fd >= 0)
335 close(dummy_fd); 372 close(dummy_fd);
336 if (pipe_fds[0] >= 0) 373 if (pipe_fds[0] >= 0)
337 close(pipe_fds[0]); 374 close(pipe_fds[0]);
338 if (pipe_fds[1] >= 0) 375 if (pipe_fds[1] >= 0)
339 close(pipe_fds[1]); 376 close(pipe_fds[1]);
340 return -1; 377 return -1;
341 } 378 }
342 379
343 // Handle a 'fork' request from the browser: this means that the browser 380 // Handle a 'fork' request from the browser: this means that the browser
344 // wishes to start a new renderer. 381 // wishes to start a new renderer.
345 bool HandleForkRequest(int fd, const Pickle& pickle, void* iter, 382 bool HandleForkRequest(int fd, const Pickle& pickle,
346 std::vector<int>& fds) { 383 void* iter, std::vector<int>& fds,
384 const std::string process_type) {
Evan Martin 2011/06/24 18:57:33 Pass by reference, not copy
Brad Chen 2011/06/25 22:14:51 As per your suggestion I'm no longer passing proce
347 std::vector<std::string> args; 385 std::vector<std::string> args;
348 int argc, numfds; 386 int argc, numfds;
349 base::GlobalDescriptors::Mapping mapping; 387 base::GlobalDescriptors::Mapping mapping;
350 base::ProcessId child; 388 base::ProcessId child;
351 389
352 if (!pickle.ReadInt(&iter, &argc)) 390 if (!pickle.ReadInt(&iter, &argc))
353 goto error; 391 goto error;
354 392
355 for (int i = 0; i < argc; ++i) { 393 for (int i = 0; i < argc; ++i) {
356 std::string arg; 394 std::string arg;
(...skipping 10 matching lines...) Expand all
367 for (int i = 0; i < numfds; ++i) { 405 for (int i = 0; i < numfds; ++i) {
368 base::GlobalDescriptors::Key key; 406 base::GlobalDescriptors::Key key;
369 if (!pickle.ReadUInt32(&iter, &key)) 407 if (!pickle.ReadUInt32(&iter, &key))
370 goto error; 408 goto error;
371 mapping.push_back(std::make_pair(key, fds[i])); 409 mapping.push_back(std::make_pair(key, fds[i]));
372 } 410 }
373 411
374 mapping.push_back(std::make_pair( 412 mapping.push_back(std::make_pair(
375 static_cast<uint32_t>(kSandboxIPCChannel), kMagicSandboxIPCDescriptor)); 413 static_cast<uint32_t>(kSandboxIPCChannel), kMagicSandboxIPCDescriptor));
376 414
377 child = ForkWithRealPid(); 415 child = ForkWithRealPid(process_type, fds,
416 ExtractArg(args, switches::kProcessChannelID));
378 417
379 if (!child) { 418 if (!child) {
380 #if defined(SECCOMP_SANDBOX) 419 #if defined(SECCOMP_SANDBOX)
381 // 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
382 if (g_proc_fd >= 0) { 421 if (g_proc_fd >= 0) {
383 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);
384 if (proc_self_maps >= 0) { 423 if (proc_self_maps >= 0) {
385 SeccompSandboxSetProcSelfMaps(proc_self_maps); 424 SeccompSandboxSetProcSelfMaps(proc_self_maps);
386 } 425 }
387 close(g_proc_fd); 426 close(g_proc_fd);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 return false; 479 return false;
441 } 480 }
442 481
443 // 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
444 // 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
445 // into the sandbox PID namespace. 484 // into the sandbox PID namespace.
446 typedef base::hash_map<base::ProcessHandle, base::ProcessHandle> ProcessMap; 485 typedef base::hash_map<base::ProcessHandle, base::ProcessHandle> ProcessMap;
447 ProcessMap real_pids_to_sandbox_pids; 486 ProcessMap real_pids_to_sandbox_pids;
448 487
449 const int sandbox_flags_; 488 const int sandbox_flags_;
489 ZygoteForkDelegate* helper_;
450 }; 490 };
451 491
452 // With SELinux we can carve out a precise sandbox, so we don't have to play 492 // With SELinux we can carve out a precise sandbox, so we don't have to play
453 // with intercepting libc calls. 493 // with intercepting libc calls.
454 #if !defined(CHROMIUM_SELINUX) 494 #if !defined(CHROMIUM_SELINUX)
455 495
456 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output, 496 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output,
457 char* timezone_out, 497 char* timezone_out,
458 size_t timezone_out_len) { 498 size_t timezone_out_len) {
459 Pickle request; 499 Pickle request;
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 #else // CHROMIUM_SELINUX 738 #else // CHROMIUM_SELINUX
699 739
700 static bool EnterSandbox() { 740 static bool EnterSandbox() {
701 PreSandboxInit(); 741 PreSandboxInit();
702 SkiaFontConfigUseIPCImplementation(kMagicSandboxIPCDescriptor); 742 SkiaFontConfigUseIPCImplementation(kMagicSandboxIPCDescriptor);
703 return true; 743 return true;
704 } 744 }
705 745
706 #endif // CHROMIUM_SELINUX 746 #endif // CHROMIUM_SELINUX
707 747
708 bool ZygoteMain(const MainFunctionParams& params) { 748 bool ZygoteMain(const MainFunctionParams& params,
749 ZygoteForkDelegate* forkdelegate) {
709 #if !defined(CHROMIUM_SELINUX) 750 #if !defined(CHROMIUM_SELINUX)
710 g_am_zygote_or_renderer = true; 751 g_am_zygote_or_renderer = true;
711 #endif 752 #endif
712 753
713 #if defined(SECCOMP_SANDBOX) 754 #if defined(SECCOMP_SANDBOX)
714 // The seccomp sandbox needs access to files in /proc, which might be denied 755 // The seccomp sandbox needs access to files in /proc, which might be denied
715 // after one of the other sandboxes have been started. So, obtain a suitable 756 // after one of the other sandboxes have been started. So, obtain a suitable
716 // file handle in advance. 757 // file handle in advance.
717 if (CommandLine::ForCurrentProcess()->HasSwitch( 758 if (CommandLine::ForCurrentProcess()->HasSwitch(
718 switches::kEnableSeccompSandbox)) { 759 switches::kEnableSeccompSandbox)) {
719 g_proc_fd = open("/proc", O_DIRECTORY | O_RDONLY); 760 g_proc_fd = open("/proc", O_DIRECTORY | O_RDONLY);
720 if (g_proc_fd < 0) { 761 if (g_proc_fd < 0) {
721 LOG(ERROR) << "WARNING! Cannot access \"/proc\". Disabling seccomp " 762 LOG(ERROR) << "WARNING! Cannot access \"/proc\". Disabling seccomp "
722 "sandboxing."; 763 "sandboxing.";
723 } 764 }
724 } 765 }
725 #endif // SECCOMP_SANDBOX 766 #endif // SECCOMP_SANDBOX
726 767
768 // initialize the fork helper
Evan Martin 2011/06/24 18:57:33 This comment is uninformative. I suggest deleting
Brad Chen 2011/06/25 22:14:51 Done.
769 VLOG(1) << "initializing fork delegate";
770 forkdelegate->Init(getenv("SBX_D") != NULL, // g_suid_sandbox_active,
771 kBrowserDescriptor, kMagicSandboxIPCDescriptor);
772
727 // Turn on the SELinux or SUID sandbox 773 // Turn on the SELinux or SUID sandbox
728 if (!EnterSandbox()) { 774 if (!EnterSandbox()) {
729 LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: " 775 LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: "
730 << errno << ")"; 776 << errno << ")";
731 return false; 777 return false;
732 } 778 }
733 779
734 int sandbox_flags = 0; 780 int sandbox_flags = 0;
735 if (getenv("SBX_D")) 781 if (getenv("SBX_D"))
736 sandbox_flags |= ZygoteHost::kSandboxSUID; 782 sandbox_flags |= ZygoteHost::kSandboxSUID;
(...skipping 16 matching lines...) Expand all
753 LOG(ERROR) << "WARNING! This machine lacks support needed for the " 799 LOG(ERROR) << "WARNING! This machine lacks support needed for the "
754 "Seccomp sandbox. Running renderers with Seccomp " 800 "Seccomp sandbox. Running renderers with Seccomp "
755 "sandboxing disabled."; 801 "sandboxing disabled.";
756 } else { 802 } else {
757 VLOG(1) << "Enabling experimental Seccomp sandbox."; 803 VLOG(1) << "Enabling experimental Seccomp sandbox.";
758 sandbox_flags |= ZygoteHost::kSandboxSeccomp; 804 sandbox_flags |= ZygoteHost::kSandboxSeccomp;
759 } 805 }
760 } 806 }
761 #endif // SECCOMP_SANDBOX 807 #endif // SECCOMP_SANDBOX
762 808
763 Zygote zygote(sandbox_flags); 809 Zygote zygote(sandbox_flags, forkdelegate);
764 // This function call can return multiple times, once per fork(). 810 // This function call can return multiple times, once per fork().
765 return zygote.ProcessRequests(); 811 return zygote.ProcessRequests();
766 } 812 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698