| 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 long number_of_cores; | 43 long number_of_cores; |
| 44 }; | 44 }; |
| 45 | 45 |
| 46 // The child must mimic the behavior of zygote_main_linux.cc on the child | 46 // The child must mimic the behavior of zygote_main_linux.cc on the child |
| 47 // side of the fork. See zygote_main_linux.cc:HandleForkRequest from | 47 // side of the fork. See zygote_main_linux.cc:HandleForkRequest from |
| 48 // if (!child) { | 48 // if (!child) { |
| 49 void BecomeNaClLoader(const std::vector<int>& child_fds, | 49 void BecomeNaClLoader(const std::vector<int>& child_fds, |
| 50 const NaClLoaderSystemInfo& system_info) { | 50 const NaClLoaderSystemInfo& system_info) { |
| 51 VLOG(1) << "NaCl loader: setting up IPC descriptor"; | 51 VLOG(1) << "NaCl loader: setting up IPC descriptor"; |
| 52 // don't need zygote FD any more | 52 // don't need zygote FD any more |
| 53 if (HANDLE_EINTR(close(kNaClZygoteDescriptor)) != 0) | 53 if (IGNORE_EINTR(close(kNaClZygoteDescriptor)) != 0) |
| 54 LOG(ERROR) << "close(kNaClZygoteDescriptor) failed."; | 54 LOG(ERROR) << "close(kNaClZygoteDescriptor) failed."; |
| 55 bool sandbox_initialized = InitializeBpfSandbox(); | 55 bool sandbox_initialized = InitializeBpfSandbox(); |
| 56 if (!sandbox_initialized) { | 56 if (!sandbox_initialized) { |
| 57 LOG(ERROR) << "Could not initialize NaCl's second " | 57 LOG(ERROR) << "Could not initialize NaCl's second " |
| 58 << "layer sandbox (seccomp-bpf)."; | 58 << "layer sandbox (seccomp-bpf)."; |
| 59 } | 59 } |
| 60 base::GlobalDescriptors::GetInstance()->Set( | 60 base::GlobalDescriptors::GetInstance()->Set( |
| 61 kPrimaryIPCChannel, | 61 kPrimaryIPCChannel, |
| 62 child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]); | 62 child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]); |
| 63 | 63 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 91 LOG(ERROR) << "read returned " << nread; | 91 LOG(ERROR) << "read returned " << nread; |
| 92 } else if (nread > static_cast<int>(len)) { | 92 } else if (nread > static_cast<int>(len)) { |
| 93 if (switch_prefix.compare(0, len, buffer, 0, len) == 0) { | 93 if (switch_prefix.compare(0, len, buffer, 0, len) == 0) { |
| 94 VLOG(1) << "NaCl loader is synchronised with Chrome zygote"; | 94 VLOG(1) << "NaCl loader is synchronised with Chrome zygote"; |
| 95 CommandLine::ForCurrentProcess()->AppendSwitchASCII( | 95 CommandLine::ForCurrentProcess()->AppendSwitchASCII( |
| 96 switches::kProcessChannelID, | 96 switches::kProcessChannelID, |
| 97 std::string(&buffer[len], nread - len)); | 97 std::string(&buffer[len], nread - len)); |
| 98 validack = true; | 98 validack = true; |
| 99 } | 99 } |
| 100 } | 100 } |
| 101 if (HANDLE_EINTR(close(dummy_fd)) != 0) | 101 if (IGNORE_EINTR(close(dummy_fd)) != 0) |
| 102 LOG(ERROR) << "close(dummy_fd) failed"; | 102 LOG(ERROR) << "close(dummy_fd) failed"; |
| 103 if (HANDLE_EINTR(close(parent_fd)) != 0) | 103 if (IGNORE_EINTR(close(parent_fd)) != 0) |
| 104 LOG(ERROR) << "close(parent_fd) failed"; | 104 LOG(ERROR) << "close(parent_fd) failed"; |
| 105 if (validack) { | 105 if (validack) { |
| 106 BecomeNaClLoader(child_fds, system_info); | 106 BecomeNaClLoader(child_fds, system_info); |
| 107 } else { | 107 } else { |
| 108 LOG(ERROR) << "Failed to synch with zygote"; | 108 LOG(ERROR) << "Failed to synch with zygote"; |
| 109 } | 109 } |
| 110 _exit(1); | 110 _exit(1); |
| 111 } | 111 } |
| 112 | 112 |
| 113 // Handle a fork request from the Zygote. | 113 // Handle a fork request from the Zygote. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 130 | 130 |
| 131 if (child_pid == 0) { | 131 if (child_pid == 0) { |
| 132 ChildNaClLoaderInit(child_fds, system_info); | 132 ChildNaClLoaderInit(child_fds, system_info); |
| 133 NOTREACHED(); | 133 NOTREACHED(); |
| 134 } | 134 } |
| 135 | 135 |
| 136 // I am the parent. | 136 // I am the parent. |
| 137 // First, close the dummy_fd so the sandbox won't find me when | 137 // First, close the dummy_fd so the sandbox won't find me when |
| 138 // looking for the child's pid in /proc. Also close other fds. | 138 // looking for the child's pid in /proc. Also close other fds. |
| 139 for (size_t i = 0; i < child_fds.size(); i++) { | 139 for (size_t i = 0; i < child_fds.size(); i++) { |
| 140 if (HANDLE_EINTR(close(child_fds[i])) != 0) | 140 if (IGNORE_EINTR(close(child_fds[i])) != 0) |
| 141 LOG(ERROR) << "close(child_fds[i]) failed"; | 141 LOG(ERROR) << "close(child_fds[i]) failed"; |
| 142 } | 142 } |
| 143 VLOG(1) << "nacl_helper: child_pid is " << child_pid; | 143 VLOG(1) << "nacl_helper: child_pid is " << child_pid; |
| 144 | 144 |
| 145 // Now send child_pid (eventually -1 if fork failed) to the Chrome Zygote. | 145 // Now send child_pid (eventually -1 if fork failed) to the Chrome Zygote. |
| 146 output_pickle->WriteInt(child_pid); | 146 output_pickle->WriteInt(child_pid); |
| 147 return true; | 147 return true; |
| 148 } | 148 } |
| 149 | 149 |
| 150 bool HandleGetTerminationStatusRequest(PickleIterator* input_iter, | 150 bool HandleGetTerminationStatusRequest(PickleIterator* input_iter, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 173 status = base::GetTerminationStatus(child_to_wait, &exit_code); | 173 status = base::GetTerminationStatus(child_to_wait, &exit_code); |
| 174 output_pickle->WriteInt(static_cast<int>(status)); | 174 output_pickle->WriteInt(static_cast<int>(status)); |
| 175 output_pickle->WriteInt(exit_code); | 175 output_pickle->WriteInt(exit_code); |
| 176 return true; | 176 return true; |
| 177 } | 177 } |
| 178 | 178 |
| 179 // This is a poor man's check on whether we are sandboxed. | 179 // This is a poor man's check on whether we are sandboxed. |
| 180 bool IsSandboxed() { | 180 bool IsSandboxed() { |
| 181 int proc_fd = open("/proc/self/exe", O_RDONLY); | 181 int proc_fd = open("/proc/self/exe", O_RDONLY); |
| 182 if (proc_fd >= 0) { | 182 if (proc_fd >= 0) { |
| 183 HANDLE_EINTR(close(proc_fd)); | 183 close(proc_fd); |
| 184 return false; | 184 return false; |
| 185 } | 185 } |
| 186 return true; | 186 return true; |
| 187 } | 187 } |
| 188 | 188 |
| 189 // Honor a command |command_type|. Eventual command parameters are | 189 // Honor a command |command_type|. Eventual command parameters are |
| 190 // available in |input_iter| and eventual file descriptors attached to | 190 // available in |input_iter| and eventual file descriptors attached to |
| 191 // the command are in |attached_fds|. | 191 // the command are in |attached_fds|. |
| 192 // Reply to the command on |reply_fds|. | 192 // Reply to the command on |reply_fds|. |
| 193 bool HonorRequestAndReply(int reply_fd, | 193 bool HonorRequestAndReply(int reply_fd, |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 // Now handle requests from the Zygote. | 381 // Now handle requests from the Zygote. |
| 382 while (true) { | 382 while (true) { |
| 383 bool request_handled = HandleZygoteRequest(kNaClZygoteDescriptor, | 383 bool request_handled = HandleZygoteRequest(kNaClZygoteDescriptor, |
| 384 system_info); | 384 system_info); |
| 385 // Do not turn this into a CHECK() without thinking about robustness | 385 // Do not turn this into a CHECK() without thinking about robustness |
| 386 // against malicious IPC requests. | 386 // against malicious IPC requests. |
| 387 DCHECK(request_handled); | 387 DCHECK(request_handled); |
| 388 } | 388 } |
| 389 NOTREACHED(); | 389 NOTREACHED(); |
| 390 } | 390 } |
| OLD | NEW |