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 |