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

Side by Side Diff: chrome/nacl/nacl_helper_linux.cc

Issue 6995121: New NaCl zygote implementation 2 (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Fixing includes for checkdeps.py 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
(Empty)
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
3 // found in the LICENSE file.
4
5 // A mini-zygote specifically for Native Client.
6
7 #include <errno.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <unistd.h>
14
15 #include <vector>
16
17 #include "base/at_exit.h"
18 #include "base/command_line.h"
19 #include "base/eintr_wrapper.h"
20 #include "base/mac/scoped_nsautorelease_pool.h"
21 #include "base/rand_util.h"
22 #include "chrome/common/nacl_helper_linux.h"
23 #include "content/common/main_function_params.h"
24 #include "content/common/unix_domain_socket_posix.h"
25
26 // We define DCHECK internally instead of including base/logging.h
27 // from Chromium, in hopes of avoiding a large dependency tree. The
28 // goal is to make the nacl_helper binary small, as it is a new
29 // binary in the Chrome linux distribution.
Mark Seaborn 2011/06/15 16:09:04 'linux' -> 'Linux'
Brad Chen 2011/06/15 18:47:47 Done.
30 #if defined(NDEBUG)
31 #define DCHECK(condition) {}
32 #define DEBUG(s) do { if (0) { s; } } while (0)
33 #else
34 #define DCHECK(condition) \
35 { if (!condition) fprintf(stderr, "Check failed: %s.\n", #condition); }
36 #define DEBUG(s) s
37 #endif
38
39 #if !defined(NDEBUG)
40 class GURL;
41 // This is another attempt to reduce binary size by pruning dependencies.
42 // These two symbols from webkit_glue are being referenced someplace
43 // in debug builds but apparently are not being called. I do not know
44 // from where they are referenced, but as long as it's not in release
45 // builds this seems okay.
46 namespace webkit_glue {
47
48 bool FindProxyForUrl(const GURL& url, std::string* proxy_list) {
jam 2011/06/15 00:35:31 btw this same approach is used with the nacl win64
49 fprintf(stderr, "Who is calling FindProxyForUrl?");
50 _exit(-1);
51 return false;
52 }
53
54 std::string GetProductVersion() {
55 fprintf(stderr, "Who is calling GetProductVersion?");
56 _exit(-1);
57 return "";
58 }
59
60 } // namespace webkit_glue
61 #endif // NDEBUG
62
63 static bool g_suid_sandbox_active;
64 extern int NaClMain(const MainFunctionParams&);
65
66 // The child must mimic the behavior of zygote_main_linux.c on the child
67 // side of the fork. See zygote_main_linux.cc:HandleForkRequest from
68 // if (!child) {
69 // Note: this code doesn't attempt to support SELINUX or the SECCOMP sandbox.
70 static void BecomeNaClLoader(const int zygote_fd,
71 const std::vector<int>& child_fds) {
72 // Set up zygote descriptor as required by Chrome
73 DCHECK(zygote_fd == kNaClZygoteDescriptor);
74 close(zygote_fd);
75 int zfd = dup2(child_fds[kNaClBrowserFDIndex], kNaClZygoteDescriptor);
76 if (zfd != kNaClZygoteDescriptor) {
77 fprintf(stderr, "Could not initialize kNaClZygoteDescriptor (%d)\n", zfd);
78 _exit(-1);
79 }
80 // Set up sandbox descriptor as required by Chrome
81 close(kNaClSandboxDescriptor);
82 int sandbox_fd = dup2(child_fds[kNaClSandboxFDIndex], kNaClSandboxDescriptor);
83 if (sandbox_fd != kNaClSandboxDescriptor) {
84 fprintf(stderr, "Could not initialize kSandboxDescriptor (%d)\n",
85 sandbox_fd);
86 _exit(-1);
87 }
88
89 base::mac::ScopedNSAutoreleasePool autorelease_pool;
90 SandboxInitWrapper sandbox_wrapper;
91 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
92 const MainFunctionParams mainparams(command_line,
93 sandbox_wrapper,
94 &autorelease_pool);
95
96 DEBUG(fprintf(stderr, "calling NaClMain\n"));
97 NaClMain(mainparams);
98 _exit(0);
99 }
100
101 // Some of this code was lifted from
102 // content/browser/zygote_main_linux.cc:ForkWithRealPid()
103 static void HandleForkRequest(const int zygote_fd,
104 const std::vector<int>& child_fds) {
105 pid_t childpid = fork();
106 if (childpid < 0) {
107 perror("fork");
108 fprintf(stderr, "*** HandleForkRequest failed\n");
109 // fall through to parent case below
110 } else if (childpid == 0) { // In the child process.
111 if (g_suid_sandbox_active) {
112 char buffer[1];
113 // Wait until the parent process has discovered our PID. We
114 // should not fork any child processes (which the seccomp
115 // sandbox does) until then, because that can interfere with the
116 // parent's discovery of our PID.
117 int nread = HANDLE_EINTR(read(child_fds[kNaClParentFDIndex], buffer, 1));
118 if (nread != 1 || buffer[0] != 'x') {
119 perror("read");
Mark Seaborn 2011/06/15 16:09:04 You're calling perror() when read() did not necess
Brad Chen 2011/06/15 18:47:47 Done.
120 fprintf(stderr, "Failed to synch with zygote (%d:%d)\n",
121 nread, buffer[0]);
122 } else {
123 DEBUG(fprintf(stderr,
124 "NaCl loader is synchronised with Chrome zygote\n"));
125 }
126 }
127 close(child_fds[kNaClDummyFDIndex]);
128 close(child_fds[kNaClParentFDIndex]);
129 BecomeNaClLoader(zygote_fd, child_fds);
130 // NOTREACHED
131 return;
132 }
133 // I am the parent.
134 // First, close the dummy_fd so the sandbox won't find me when
135 // looking for the child's pid in /proc. Also close other fds.
136 for (size_t i = 0; i < child_fds.size(); i++) {
137 close(child_fds[i]);
138 }
139 // Now tell childpid to the Chrome zygote.
140 if (HANDLE_EINTR(send(zygote_fd, &childpid, sizeof(childpid), MSG_EOR))
141 != sizeof(childpid)) {
142 fprintf(stderr, "*** send() to zygote failed");
143 }
144 }
145
146 int main(int argc, char *argv[]) {
147 CommandLine::Init(argc, argv);
148 base::AtExitManager exit_manager;
149 base::RandUint64(); // acquire /dev/urandom fd before sandbox is raised
150
151 g_suid_sandbox_active = (NULL != getenv("SBX_D"));
152
153 if (HANDLE_EINTR(send(kNaClZygoteDescriptor, kNaClHelperMagic,
Mark Seaborn 2011/06/15 16:09:04 Please put a comment in about why you are sending
Brad Chen 2011/06/15 18:47:47 Done.
154 sizeof(kNaClHelperMagic), MSG_EOR)) !=
Mark Seaborn 2011/06/15 16:09:04 I've not seen MSG_EOR before. What function is it
Brad Chen 2011/06/15 18:47:47 It is to terminate the message for the UnixDomainS
155 sizeof(kNaClHelperMagic)) {
156 perror("send");
157 }
158
159 while (true) {
160 int badpid = -1;
161 std::vector<int> fds;
162 static const unsigned kMaxMessageLength = 2048;
163 char buf[kMaxMessageLength];
164 const ssize_t msglen = UnixDomainSocket::RecvMsg(kNaClZygoteDescriptor,
165 &buf, sizeof(buf), &fds);
166 if (0 == msglen || (-1 == msglen && ECONNRESET == errno)) {
167 // EOF from zygote. Rest in peace...
Mark Seaborn 2011/06/15 16:09:04 Note that since this process is sharing an FD tabl
Brad Chen 2011/06/15 18:47:47 I've confirmed that the nacl_helper gets cleaned w
168 _exit(0);
169 return 0;
170 }
171 if (msglen == -1) {
172 fprintf(stderr, "NaCl helper: error reading message from zygote\n");
173 continue;
174 }
175 // fork request
176 if (msglen == sizeof(kNaClForkRequest) &&
177 memcmp(buf, kNaClForkRequest, msglen) == 0) {
178 if (kNaClSandboxFDIndex + 1 == fds.size() ||
179 kNaClParentFDIndex + 1 == fds.size()) {
180 HandleForkRequest(kNaClZygoteDescriptor, fds);
181 // child does not return
182 } else {
183 fprintf(stderr, "NaCl helper expected 2 or 4 fds, got %d\n",
184 int(fds.size()));
185 }
186 } else {
187 fprintf(stderr, "NaCl helper unrecognized request: %s\n", buf);
188 }
189 if (HANDLE_EINTR(send(kNaClZygoteDescriptor, &badpid,
190 sizeof(badpid), MSG_EOR)) != sizeof(badpid)) {
191 perror("send");
Mark Seaborn 2011/06/15 16:09:04 This is called in cases where send() didn't return
Brad Chen 2011/06/15 18:47:47 Done.
192 }
193 }
194 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698