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

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

Issue 7230057: Revert 90805 - I am submitting this with LGTMs from agl@ and evanm@. I'm marking this as TBR=jam@... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: 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
« no previous file with comments | « content/browser/zygote_host_linux.cc ('k') | content/common/content_switches.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:mergeinfo
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"
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « content/browser/zygote_host_linux.cc ('k') | content/common/content_switches.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698