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

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: Missing include... Created 9 years, 5 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 // Search through string vector args for a string of the form
98 // --swtch=value. Return the string if found, else return the
99 // empty string.
Evan Martin 2011/06/27 18:49:32 I'm a little concerned that this is incorrect for
Brad Chen 2011/06/27 22:06:25 I never liked this code this much anyway. Realizin
100 static std::string ExtractArg(std::vector<std::string>& args,
101 const std::string& swtch) {
102 const std::string key = "--" + swtch + "=";
103 int len = key.length();
104 for (size_t i = 0; i < args.size(); i++) {
105 if (key.compare(0, len, args[i], 0, len) == 0) {
106 return args[i];
107 }
108 }
109 return "";
110 }
111
95 // This is the object which implements the zygote. The ZygoteMain function, 112 // This is the object which implements the zygote. The ZygoteMain function,
96 // which is called from ChromeMain, simply constructs one of these objects and 113 // which is called from ChromeMain, simply constructs one of these objects and
97 // runs it. 114 // runs it.
98 class Zygote { 115 class Zygote {
99 public: 116 public:
100 explicit Zygote(int sandbox_flags) 117 explicit Zygote(int sandbox_flags, ZygoteForkDelegate* helper)
101 : sandbox_flags_(sandbox_flags) { 118 : sandbox_flags_(sandbox_flags),
119 helper_(helper) {
102 } 120 }
103 121
104 bool ProcessRequests() { 122 bool ProcessRequests() {
105 // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the 123 // A SOCK_SEQPACKET socket is installed in fd 3. We get commands from the
106 // browser on it. 124 // browser on it.
107 // A SOCK_DGRAM is installed in fd 5. This is the sandbox IPC channel. 125 // A SOCK_DGRAM is installed in fd 5. This is the sandbox IPC channel.
108 // See http://code.google.com/p/chromium/wiki/LinuxSandboxIPC 126 // See http://code.google.com/p/chromium/wiki/LinuxSandboxIPC
109 127
110 // We need to accept SIGCHLD, even though our handler is a no-op because 128 // 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.) 129 // otherwise we cannot wait on children. (According to POSIX 2001.)
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 176
159 Pickle pickle(buf, len); 177 Pickle pickle(buf, len);
160 void* iter = NULL; 178 void* iter = NULL;
161 179
162 int kind; 180 int kind;
163 if (pickle.ReadInt(&iter, &kind)) { 181 if (pickle.ReadInt(&iter, &kind)) {
164 switch (kind) { 182 switch (kind) {
165 case ZygoteHost::kCmdFork: 183 case ZygoteHost::kCmdFork:
166 // This function call can return multiple times, once per fork(). 184 // This function call can return multiple times, once per fork().
167 return HandleForkRequest(fd, pickle, iter, fds); 185 return HandleForkRequest(fd, pickle, iter, fds);
186
168 case ZygoteHost::kCmdReap: 187 case ZygoteHost::kCmdReap:
169 if (!fds.empty()) 188 if (!fds.empty())
170 break; 189 break;
171 HandleReapRequest(fd, pickle, iter); 190 HandleReapRequest(fd, pickle, iter);
172 return false; 191 return false;
173 case ZygoteHost::kCmdGetTerminationStatus: 192 case ZygoteHost::kCmdGetTerminationStatus:
174 if (!fds.empty()) 193 if (!fds.empty())
175 break; 194 break;
176 HandleGetTerminationStatus(fd, pickle, iter); 195 HandleGetTerminationStatus(fd, pickle, iter);
177 return false; 196 return false;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 ssize_t written = 259 ssize_t written =
241 HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size())); 260 HANDLE_EINTR(write(fd, write_pickle.data(), write_pickle.size()));
242 if (written != static_cast<ssize_t>(write_pickle.size())) 261 if (written != static_cast<ssize_t>(write_pickle.size()))
243 PLOG(ERROR) << "write"; 262 PLOG(ERROR) << "write";
244 } 263 }
245 264
246 // This is equivalent to fork(), except that, when using the SUID 265 // This is equivalent to fork(), except that, when using the SUID
247 // sandbox, it returns the real PID of the child process as it 266 // sandbox, it returns the real PID of the child process as it
248 // appears outside the sandbox, rather than returning the PID inside 267 // appears outside the sandbox, rather than returning the PID inside
249 // the sandbox. 268 // the sandbox.
250 int ForkWithRealPid() { 269 int ForkWithRealPid(const std::string process_type, std::vector<int>& fds,
Evan Martin 2011/06/27 18:49:32 These should be const std::string&
Brad Chen 2011/06/27 22:06:25 Done.
251 if (!g_suid_sandbox_active) 270 const std::string channel_switch) {
271 const bool use_helper = (helper_ && helper_->CanHelp(process_type));
272 if (!(use_helper || g_suid_sandbox_active)) {
252 return fork(); 273 return fork();
274 }
253 275
254 int dummy_fd; 276 int dummy_fd;
255 ino_t dummy_inode; 277 ino_t dummy_inode;
256 int pipe_fds[2] = { -1, -1 }; 278 int pipe_fds[2] = { -1, -1 };
257 base::ProcessId pid = 0; 279 base::ProcessId pid = 0;
258 280
259 dummy_fd = socket(PF_UNIX, SOCK_DGRAM, 0); 281 dummy_fd = socket(PF_UNIX, SOCK_DGRAM, 0);
260 if (dummy_fd < 0) { 282 if (dummy_fd < 0) {
261 LOG(ERROR) << "Failed to create dummy FD"; 283 LOG(ERROR) << "Failed to create dummy FD";
262 goto error; 284 goto error;
263 } 285 }
264 if (!base::FileDescriptorGetInode(&dummy_inode, dummy_fd)) { 286 if (!base::FileDescriptorGetInode(&dummy_inode, dummy_fd)) {
265 LOG(ERROR) << "Failed to get inode for dummy FD"; 287 LOG(ERROR) << "Failed to get inode for dummy FD";
266 goto error; 288 goto error;
267 } 289 }
268 if (pipe(pipe_fds) != 0) { 290 if (pipe(pipe_fds) != 0) {
269 LOG(ERROR) << "Failed to create pipe"; 291 LOG(ERROR) << "Failed to create pipe";
270 goto error; 292 goto error;
271 } 293 }
272 294
273 pid = fork(); 295 if (use_helper) {
296 fds.push_back(dummy_fd);
297 fds.push_back(pipe_fds[0]);
298 pid = helper_->Fork(fds);
299 } else {
300 pid = fork();
301 }
274 if (pid < 0) { 302 if (pid < 0) {
275 goto error; 303 goto error;
276 } else if (pid == 0) { 304 } else if (pid == 0) {
277 // In the child process. 305 // In the child process.
278 close(pipe_fds[1]); 306 close(pipe_fds[1]);
279 char buffer[1]; 307 char buffer[1];
280 // Wait until the parent process has discovered our PID. We 308 // Wait until the parent process has discovered our PID. We
281 // should not fork any child processes (which the seccomp 309 // should not fork any child processes (which the seccomp
282 // sandbox does) until then, because that can interfere with the 310 // sandbox does) until then, because that can interfere with the
283 // parent's discovery of our PID. 311 // parent's discovery of our PID.
284 if (HANDLE_EINTR(read(pipe_fds[0], buffer, 1)) != 1 || 312 if (HANDLE_EINTR(read(pipe_fds[0], buffer, 1)) != 1 ||
285 buffer[0] != 'x') { 313 buffer[0] != 'x') {
286 LOG(FATAL) << "Failed to synchronise with parent zygote process"; 314 LOG(FATAL) << "Failed to synchronise with parent zygote process";
287 } 315 }
288 close(pipe_fds[0]); 316 close(pipe_fds[0]);
289 close(dummy_fd); 317 close(dummy_fd);
290 return 0; 318 return 0;
291 } else { 319 } else {
292 // In the parent process. 320 // In the parent process.
293 close(dummy_fd); 321 close(dummy_fd);
294 dummy_fd = -1; 322 dummy_fd = -1;
295 close(pipe_fds[0]); 323 close(pipe_fds[0]);
296 pipe_fds[0] = -1; 324 pipe_fds[0] = -1;
297 uint8_t reply_buf[512]; 325 base::ProcessId real_pid;
298 Pickle request; 326 if (g_suid_sandbox_active) {
299 request.WriteInt(LinuxSandbox::METHOD_GET_CHILD_WITH_INODE); 327 uint8_t reply_buf[512];
300 request.WriteUInt64(dummy_inode); 328 Pickle request;
329 request.WriteInt(LinuxSandbox::METHOD_GET_CHILD_WITH_INODE);
330 request.WriteUInt64(dummy_inode);
301 331
302 const ssize_t r = UnixDomainSocket::SendRecvMsg( 332 const ssize_t r = UnixDomainSocket::SendRecvMsg(
303 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL, 333 kMagicSandboxIPCDescriptor, reply_buf, sizeof(reply_buf), NULL,
304 request); 334 request);
305 if (r == -1) { 335 if (r == -1) {
306 LOG(ERROR) << "Failed to get child process's real PID"; 336 LOG(ERROR) << "Failed to get child process's real PID";
307 goto error; 337 goto error;
338 }
339
340 Pickle reply(reinterpret_cast<char*>(reply_buf), r);
341 void* iter2 = NULL;
Evan Martin 2011/06/27 18:49:32 Why "iter2" and not just "iter"?
Brad Chen 2011/06/27 22:06:25 An irrelevant artifact; fixed. On 2011/06/27 18:4
342 if (!reply.ReadInt(&iter2, &real_pid))
343 goto error;
344 if (real_pid <= 0) {
345 // METHOD_GET_CHILD_WITH_INODE failed. Did the child die already?
346 LOG(ERROR) << "METHOD_GET_CHILD_WITH_INODE failed";
347 goto error;
348 }
349 real_pids_to_sandbox_pids[real_pid] = pid;
308 } 350 }
309 351 if (use_helper) {
310 base::ProcessId real_pid; 352 real_pid = pid;
311 Pickle reply(reinterpret_cast<char*>(reply_buf), r); 353 if (!helper_->AckChild(pipe_fds[1], channel_switch)) {
312 void* iter2 = NULL; 354 LOG(ERROR) << "Failed to synchronise with NaCl child process";
313 if (!reply.ReadInt(&iter2, &real_pid)) 355 goto error;
314 goto error; 356 }
315 if (real_pid <= 0) { 357 } else {
316 // METHOD_GET_CHILD_WITH_INODE failed. Did the child die already? 358 if (HANDLE_EINTR(write(pipe_fds[1], "x", 1)) != 1) {
317 LOG(ERROR) << "METHOD_GET_CHILD_WITH_INODE failed"; 359 LOG(ERROR) << "Failed to synchronise with child process";
318 goto error; 360 goto error;
319 } 361 }
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 } 362 }
325 close(pipe_fds[1]); 363 close(pipe_fds[1]);
326 return real_pid; 364 return real_pid;
327 } 365 }
328 366
329 error: 367 error:
330 if (pid > 0) { 368 if (pid > 0) {
331 if (waitpid(pid, NULL, WNOHANG) == -1) 369 if (waitpid(pid, NULL, WNOHANG) == -1)
332 LOG(ERROR) << "Failed to wait for process"; 370 LOG(ERROR) << "Failed to wait for process";
333 } 371 }
334 if (dummy_fd >= 0) 372 if (dummy_fd >= 0)
335 close(dummy_fd); 373 close(dummy_fd);
336 if (pipe_fds[0] >= 0) 374 if (pipe_fds[0] >= 0)
337 close(pipe_fds[0]); 375 close(pipe_fds[0]);
338 if (pipe_fds[1] >= 0) 376 if (pipe_fds[1] >= 0)
339 close(pipe_fds[1]); 377 close(pipe_fds[1]);
340 return -1; 378 return -1;
341 } 379 }
342 380
343 // Handle a 'fork' request from the browser: this means that the browser 381 // Handle a 'fork' request from the browser: this means that the browser
344 // wishes to start a new renderer. 382 // wishes to start a new renderer.
345 bool HandleForkRequest(int fd, const Pickle& pickle, void* iter, 383 bool HandleForkRequest(int fd, const Pickle& pickle,
346 std::vector<int>& fds) { 384 void* iter, std::vector<int>& fds) {
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;
389 std::string process_type;
390
391 if (!pickle.ReadString(&iter, &process_type))
392 goto error;
351 393
352 if (!pickle.ReadInt(&iter, &argc)) 394 if (!pickle.ReadInt(&iter, &argc))
353 goto error; 395 goto error;
354 396
355 for (int i = 0; i < argc; ++i) { 397 for (int i = 0; i < argc; ++i) {
356 std::string arg; 398 std::string arg;
357 if (!pickle.ReadString(&iter, &arg)) 399 if (!pickle.ReadString(&iter, &arg))
358 goto error; 400 goto error;
359 args.push_back(arg); 401 args.push_back(arg);
360 } 402 }
361 403
362 if (!pickle.ReadInt(&iter, &numfds)) 404 if (!pickle.ReadInt(&iter, &numfds))
363 goto error; 405 goto error;
364 if (numfds != static_cast<int>(fds.size())) 406 if (numfds != static_cast<int>(fds.size()))
365 goto error; 407 goto error;
366 408
367 for (int i = 0; i < numfds; ++i) { 409 for (int i = 0; i < numfds; ++i) {
368 base::GlobalDescriptors::Key key; 410 base::GlobalDescriptors::Key key;
369 if (!pickle.ReadUInt32(&iter, &key)) 411 if (!pickle.ReadUInt32(&iter, &key))
370 goto error; 412 goto error;
371 mapping.push_back(std::make_pair(key, fds[i])); 413 mapping.push_back(std::make_pair(key, fds[i]));
372 } 414 }
373 415
374 mapping.push_back(std::make_pair( 416 mapping.push_back(std::make_pair(
375 static_cast<uint32_t>(kSandboxIPCChannel), kMagicSandboxIPCDescriptor)); 417 static_cast<uint32_t>(kSandboxIPCChannel), kMagicSandboxIPCDescriptor));
376 418
377 child = ForkWithRealPid(); 419 child = ForkWithRealPid(process_type, fds,
420 ExtractArg(args, switches::kProcessChannelID));
378 421
379 if (!child) { 422 if (!child) {
380 #if defined(SECCOMP_SANDBOX) 423 #if defined(SECCOMP_SANDBOX)
381 // Try to open /proc/self/maps as the seccomp sandbox needs access to it 424 // Try to open /proc/self/maps as the seccomp sandbox needs access to it
382 if (g_proc_fd >= 0) { 425 if (g_proc_fd >= 0) {
383 int proc_self_maps = openat(g_proc_fd, "self/maps", O_RDONLY); 426 int proc_self_maps = openat(g_proc_fd, "self/maps", O_RDONLY);
384 if (proc_self_maps >= 0) { 427 if (proc_self_maps >= 0) {
385 SeccompSandboxSetProcSelfMaps(proc_self_maps); 428 SeccompSandboxSetProcSelfMaps(proc_self_maps);
386 } 429 }
387 close(g_proc_fd); 430 close(g_proc_fd);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 return false; 483 return false;
441 } 484 }
442 485
443 // In the SUID sandbox, we try to use a new PID namespace. Thus the PIDs 486 // 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 487 // fork() returns are not the real PIDs, so we need to map the Real PIDS
445 // into the sandbox PID namespace. 488 // into the sandbox PID namespace.
446 typedef base::hash_map<base::ProcessHandle, base::ProcessHandle> ProcessMap; 489 typedef base::hash_map<base::ProcessHandle, base::ProcessHandle> ProcessMap;
447 ProcessMap real_pids_to_sandbox_pids; 490 ProcessMap real_pids_to_sandbox_pids;
448 491
449 const int sandbox_flags_; 492 const int sandbox_flags_;
493 ZygoteForkDelegate* helper_;
450 }; 494 };
451 495
452 // With SELinux we can carve out a precise sandbox, so we don't have to play 496 // With SELinux we can carve out a precise sandbox, so we don't have to play
453 // with intercepting libc calls. 497 // with intercepting libc calls.
454 #if !defined(CHROMIUM_SELINUX) 498 #if !defined(CHROMIUM_SELINUX)
455 499
456 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output, 500 static void ProxyLocaltimeCallToBrowser(time_t input, struct tm* output,
457 char* timezone_out, 501 char* timezone_out,
458 size_t timezone_out_len) { 502 size_t timezone_out_len) {
459 Pickle request; 503 Pickle request;
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 #else // CHROMIUM_SELINUX 742 #else // CHROMIUM_SELINUX
699 743
700 static bool EnterSandbox() { 744 static bool EnterSandbox() {
701 PreSandboxInit(); 745 PreSandboxInit();
702 SkiaFontConfigUseIPCImplementation(kMagicSandboxIPCDescriptor); 746 SkiaFontConfigUseIPCImplementation(kMagicSandboxIPCDescriptor);
703 return true; 747 return true;
704 } 748 }
705 749
706 #endif // CHROMIUM_SELINUX 750 #endif // CHROMIUM_SELINUX
707 751
708 bool ZygoteMain(const MainFunctionParams& params) { 752 bool ZygoteMain(const MainFunctionParams& params,
753 ZygoteForkDelegate* forkdelegate) {
709 #if !defined(CHROMIUM_SELINUX) 754 #if !defined(CHROMIUM_SELINUX)
710 g_am_zygote_or_renderer = true; 755 g_am_zygote_or_renderer = true;
711 #endif 756 #endif
712 757
713 #if defined(SECCOMP_SANDBOX) 758 #if defined(SECCOMP_SANDBOX)
714 // The seccomp sandbox needs access to files in /proc, which might be denied 759 // 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 760 // after one of the other sandboxes have been started. So, obtain a suitable
716 // file handle in advance. 761 // file handle in advance.
717 if (CommandLine::ForCurrentProcess()->HasSwitch( 762 if (CommandLine::ForCurrentProcess()->HasSwitch(
718 switches::kEnableSeccompSandbox)) { 763 switches::kEnableSeccompSandbox)) {
719 g_proc_fd = open("/proc", O_DIRECTORY | O_RDONLY); 764 g_proc_fd = open("/proc", O_DIRECTORY | O_RDONLY);
720 if (g_proc_fd < 0) { 765 if (g_proc_fd < 0) {
721 LOG(ERROR) << "WARNING! Cannot access \"/proc\". Disabling seccomp " 766 LOG(ERROR) << "WARNING! Cannot access \"/proc\". Disabling seccomp "
722 "sandboxing."; 767 "sandboxing.";
723 } 768 }
724 } 769 }
725 #endif // SECCOMP_SANDBOX 770 #endif // SECCOMP_SANDBOX
726 771
772 VLOG(1) << "initializing fork delegate";
773 forkdelegate->Init(getenv("SBX_D") != NULL, // g_suid_sandbox_active,
774 kBrowserDescriptor, kMagicSandboxIPCDescriptor);
775
727 // Turn on the SELinux or SUID sandbox 776 // Turn on the SELinux or SUID sandbox
728 if (!EnterSandbox()) { 777 if (!EnterSandbox()) {
729 LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: " 778 LOG(FATAL) << "Failed to enter sandbox. Fail safe abort. (errno: "
730 << errno << ")"; 779 << errno << ")";
731 return false; 780 return false;
732 } 781 }
733 782
734 int sandbox_flags = 0; 783 int sandbox_flags = 0;
735 if (getenv("SBX_D")) 784 if (getenv("SBX_D"))
736 sandbox_flags |= ZygoteHost::kSandboxSUID; 785 sandbox_flags |= ZygoteHost::kSandboxSUID;
(...skipping 16 matching lines...) Expand all
753 LOG(ERROR) << "WARNING! This machine lacks support needed for the " 802 LOG(ERROR) << "WARNING! This machine lacks support needed for the "
754 "Seccomp sandbox. Running renderers with Seccomp " 803 "Seccomp sandbox. Running renderers with Seccomp "
755 "sandboxing disabled."; 804 "sandboxing disabled.";
756 } else { 805 } else {
757 VLOG(1) << "Enabling experimental Seccomp sandbox."; 806 VLOG(1) << "Enabling experimental Seccomp sandbox.";
758 sandbox_flags |= ZygoteHost::kSandboxSeccomp; 807 sandbox_flags |= ZygoteHost::kSandboxSeccomp;
759 } 808 }
760 } 809 }
761 #endif // SECCOMP_SANDBOX 810 #endif // SECCOMP_SANDBOX
762 811
763 Zygote zygote(sandbox_flags); 812 Zygote zygote(sandbox_flags, forkdelegate);
764 // This function call can return multiple times, once per fork(). 813 // This function call can return multiple times, once per fork().
765 return zygote.ProcessRequests(); 814 return zygote.ProcessRequests();
766 } 815 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698