OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 // A mini-zygote specifically for Native Client. | 5 // A mini-zygote specifically for Native Client. |
6 | 6 |
7 #include "components/nacl/loader/nacl_helper_linux.h" | 7 #include "components/nacl/loader/nacl_helper_linux.h" |
8 | 8 |
9 #include <errno.h> | 9 #include <errno.h> |
10 #include <fcntl.h> | 10 #include <fcntl.h> |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 browser_fd.Pass(), system_info, uses_nonsfi_mode, nacl_sandbox); | 162 browser_fd.Pass(), system_info, uses_nonsfi_mode, nacl_sandbox); |
163 _exit(1); | 163 _exit(1); |
164 } | 164 } |
165 | 165 |
166 // Handle a fork request from the Zygote. | 166 // Handle a fork request from the Zygote. |
167 // Some of this code was lifted from | 167 // Some of this code was lifted from |
168 // content/browser/zygote_main_linux.cc:ForkWithRealPid() | 168 // content/browser/zygote_main_linux.cc:ForkWithRealPid() |
169 bool HandleForkRequest(ScopedVector<base::ScopedFD> child_fds, | 169 bool HandleForkRequest(ScopedVector<base::ScopedFD> child_fds, |
170 const NaClLoaderSystemInfo& system_info, | 170 const NaClLoaderSystemInfo& system_info, |
171 nacl::NaClSandbox* nacl_sandbox, | 171 nacl::NaClSandbox* nacl_sandbox, |
172 PickleIterator* input_iter, | 172 base::PickleIterator* input_iter, |
173 Pickle* output_pickle) { | 173 base::Pickle* output_pickle) { |
174 bool uses_nonsfi_mode; | 174 bool uses_nonsfi_mode; |
175 if (!input_iter->ReadBool(&uses_nonsfi_mode)) { | 175 if (!input_iter->ReadBool(&uses_nonsfi_mode)) { |
176 LOG(ERROR) << "Could not read uses_nonsfi_mode status"; | 176 LOG(ERROR) << "Could not read uses_nonsfi_mode status"; |
177 return false; | 177 return false; |
178 } | 178 } |
179 | 179 |
180 std::string channel_id; | 180 std::string channel_id; |
181 if (!input_iter->ReadString(&channel_id)) { | 181 if (!input_iter->ReadString(&channel_id)) { |
182 LOG(ERROR) << "Could not read channel_id string"; | 182 LOG(ERROR) << "Could not read channel_id string"; |
183 return false; | 183 return false; |
(...skipping 24 matching lines...) Expand all Loading... |
208 // First, close the dummy_fd so the sandbox won't find me when | 208 // First, close the dummy_fd so the sandbox won't find me when |
209 // looking for the child's pid in /proc. Also close other fds. | 209 // looking for the child's pid in /proc. Also close other fds. |
210 child_fds.clear(); | 210 child_fds.clear(); |
211 VLOG(1) << "nacl_helper: child_pid is " << child_pid; | 211 VLOG(1) << "nacl_helper: child_pid is " << child_pid; |
212 | 212 |
213 // Now send child_pid (eventually -1 if fork failed) to the Chrome Zygote. | 213 // Now send child_pid (eventually -1 if fork failed) to the Chrome Zygote. |
214 output_pickle->WriteInt(child_pid); | 214 output_pickle->WriteInt(child_pid); |
215 return true; | 215 return true; |
216 } | 216 } |
217 | 217 |
218 bool HandleGetTerminationStatusRequest(PickleIterator* input_iter, | 218 bool HandleGetTerminationStatusRequest(base::PickleIterator* input_iter, |
219 Pickle* output_pickle) { | 219 base::Pickle* output_pickle) { |
220 pid_t child_to_wait; | 220 pid_t child_to_wait; |
221 if (!input_iter->ReadInt(&child_to_wait)) { | 221 if (!input_iter->ReadInt(&child_to_wait)) { |
222 LOG(ERROR) << "Could not read pid to wait for"; | 222 LOG(ERROR) << "Could not read pid to wait for"; |
223 return false; | 223 return false; |
224 } | 224 } |
225 | 225 |
226 bool known_dead; | 226 bool known_dead; |
227 if (!input_iter->ReadBool(&known_dead)) { | 227 if (!input_iter->ReadBool(&known_dead)) { |
228 LOG(ERROR) << "Could not read known_dead status"; | 228 LOG(ERROR) << "Could not read known_dead status"; |
229 return false; | 229 return false; |
(...skipping 16 matching lines...) Expand all Loading... |
246 | 246 |
247 // Honor a command |command_type|. Eventual command parameters are | 247 // Honor a command |command_type|. Eventual command parameters are |
248 // available in |input_iter| and eventual file descriptors attached to | 248 // available in |input_iter| and eventual file descriptors attached to |
249 // the command are in |attached_fds|. | 249 // the command are in |attached_fds|. |
250 // Reply to the command on |reply_fds|. | 250 // Reply to the command on |reply_fds|. |
251 bool HonorRequestAndReply(int reply_fd, | 251 bool HonorRequestAndReply(int reply_fd, |
252 int command_type, | 252 int command_type, |
253 ScopedVector<base::ScopedFD> attached_fds, | 253 ScopedVector<base::ScopedFD> attached_fds, |
254 const NaClLoaderSystemInfo& system_info, | 254 const NaClLoaderSystemInfo& system_info, |
255 nacl::NaClSandbox* nacl_sandbox, | 255 nacl::NaClSandbox* nacl_sandbox, |
256 PickleIterator* input_iter) { | 256 base::PickleIterator* input_iter) { |
257 Pickle write_pickle; | 257 base::Pickle write_pickle; |
258 bool have_to_reply = false; | 258 bool have_to_reply = false; |
259 // Commands must write anything to send back to |write_pickle|. | 259 // Commands must write anything to send back to |write_pickle|. |
260 switch (command_type) { | 260 switch (command_type) { |
261 case nacl::kNaClForkRequest: | 261 case nacl::kNaClForkRequest: |
262 have_to_reply = HandleForkRequest(attached_fds.Pass(), | 262 have_to_reply = HandleForkRequest(attached_fds.Pass(), |
263 system_info, | 263 system_info, |
264 nacl_sandbox, | 264 nacl_sandbox, |
265 input_iter, | 265 input_iter, |
266 &write_pickle); | 266 &write_pickle); |
267 break; | 267 break; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 } | 302 } |
303 if (msglen == 0 || (msglen == -1 && errno == ECONNRESET)) { | 303 if (msglen == 0 || (msglen == -1 && errno == ECONNRESET)) { |
304 // EOF from the browser. Goodbye! | 304 // EOF from the browser. Goodbye! |
305 _exit(0); | 305 _exit(0); |
306 } | 306 } |
307 if (msglen < 0) { | 307 if (msglen < 0) { |
308 PLOG(ERROR) << "nacl_helper: receive from zygote failed"; | 308 PLOG(ERROR) << "nacl_helper: receive from zygote failed"; |
309 return false; | 309 return false; |
310 } | 310 } |
311 | 311 |
312 Pickle read_pickle(buf, msglen); | 312 base::Pickle read_pickle(buf, msglen); |
313 PickleIterator read_iter(read_pickle); | 313 base::PickleIterator read_iter(read_pickle); |
314 int command_type; | 314 int command_type; |
315 if (!read_iter.ReadInt(&command_type)) { | 315 if (!read_iter.ReadInt(&command_type)) { |
316 LOG(ERROR) << "Unable to read command from Zygote"; | 316 LOG(ERROR) << "Unable to read command from Zygote"; |
317 return false; | 317 return false; |
318 } | 318 } |
319 return HonorRequestAndReply(zygote_ipc_fd, | 319 return HonorRequestAndReply(zygote_ipc_fd, |
320 command_type, | 320 command_type, |
321 fds.Pass(), | 321 fds.Pass(), |
322 system_info, | 322 system_info, |
323 nacl_sandbox, | 323 nacl_sandbox, |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 // Now handle requests from the Zygote. | 477 // Now handle requests from the Zygote. |
478 while (true) { | 478 while (true) { |
479 bool request_handled = HandleZygoteRequest( | 479 bool request_handled = HandleZygoteRequest( |
480 kNaClZygoteDescriptor, system_info, nacl_sandbox.get()); | 480 kNaClZygoteDescriptor, system_info, nacl_sandbox.get()); |
481 // Do not turn this into a CHECK() without thinking about robustness | 481 // Do not turn this into a CHECK() without thinking about robustness |
482 // against malicious IPC requests. | 482 // against malicious IPC requests. |
483 DCHECK(request_handled); | 483 DCHECK(request_handled); |
484 } | 484 } |
485 NOTREACHED(); | 485 NOTREACHED(); |
486 } | 486 } |
OLD | NEW |