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

Side by Side Diff: components/nacl/loader/nacl_helper_linux.cc

Issue 1508213002: Replace ScopedVector<ScopedFD> with std::vector<ScopedFD> (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix build Created 5 years 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
OLDNEW
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>
11 #include <signal.h> 11 #include <signal.h>
12 #include <stdio.h> 12 #include <stdio.h>
13 #include <stdlib.h> 13 #include <stdlib.h>
14 #include <sys/socket.h> 14 #include <sys/socket.h>
15 #include <sys/stat.h> 15 #include <sys/stat.h>
16 #include <sys/types.h> 16 #include <sys/types.h>
17 17
18 #include <string> 18 #include <string>
19 #include <utility>
19 #include <vector> 20 #include <vector>
20 21
21 #include "base/at_exit.h" 22 #include "base/at_exit.h"
22 #include "base/command_line.h" 23 #include "base/command_line.h"
23 #include "base/files/scoped_file.h" 24 #include "base/files/scoped_file.h"
24 #include "base/logging.h" 25 #include "base/logging.h"
25 #include "base/memory/scoped_ptr.h" 26 #include "base/memory/scoped_ptr.h"
26 #include "base/memory/scoped_vector.h"
27 #include "base/message_loop/message_loop.h" 27 #include "base/message_loop/message_loop.h"
28 #include "base/posix/eintr_wrapper.h" 28 #include "base/posix/eintr_wrapper.h"
29 #include "base/posix/global_descriptors.h" 29 #include "base/posix/global_descriptors.h"
30 #include "base/posix/unix_domain_socket_linux.h" 30 #include "base/posix/unix_domain_socket_linux.h"
31 #include "base/process/kill.h" 31 #include "base/process/kill.h"
32 #include "base/process/process_handle.h" 32 #include "base/process/process_handle.h"
33 #include "base/rand_util.h" 33 #include "base/rand_util.h"
34 #include "components/nacl/common/nacl_switches.h" 34 #include "components/nacl/common/nacl_switches.h"
35 #include "components/nacl/loader/sandbox_linux/nacl_sandbox_linux.h" 35 #include "components/nacl/loader/sandbox_linux/nacl_sandbox_linux.h"
36 #include "content/public/common/content_descriptors.h" 36 #include "content/public/common/content_descriptors.h"
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 CHECK(!uses_nonsfi_mode); 125 CHECK(!uses_nonsfi_mode);
126 NaClListener listener; 126 NaClListener listener;
127 listener.set_prereserved_sandbox_size(system_info.prereserved_sandbox_size); 127 listener.set_prereserved_sandbox_size(system_info.prereserved_sandbox_size);
128 listener.set_number_of_cores(system_info.number_of_cores); 128 listener.set_number_of_cores(system_info.number_of_cores);
129 listener.Listen(); 129 listener.Listen();
130 #endif 130 #endif
131 _exit(0); 131 _exit(0);
132 } 132 }
133 133
134 // Start the NaCl loader in a child created by the NaCl loader Zygote. 134 // Start the NaCl loader in a child created by the NaCl loader Zygote.
135 void ChildNaClLoaderInit(ScopedVector<base::ScopedFD> child_fds, 135 void ChildNaClLoaderInit(std::vector<base::ScopedFD> child_fds,
136 const NaClLoaderSystemInfo& system_info, 136 const NaClLoaderSystemInfo& system_info,
137 bool uses_nonsfi_mode, 137 bool uses_nonsfi_mode,
138 nacl::NaClSandbox* nacl_sandbox, 138 nacl::NaClSandbox* nacl_sandbox,
139 const std::string& channel_id) { 139 const std::string& channel_id) {
140 DCHECK(child_fds.size() > 140 DCHECK(child_fds.size() >
141 std::max(content::ZygoteForkDelegate::kPIDOracleFDIndex, 141 std::max(content::ZygoteForkDelegate::kPIDOracleFDIndex,
142 content::ZygoteForkDelegate::kBrowserFDIndex)); 142 content::ZygoteForkDelegate::kBrowserFDIndex));
143 143
144 // Ping the PID oracle socket. 144 // Ping the PID oracle socket.
145 CHECK(content::SendZygoteChildPing( 145 CHECK(content::SendZygoteChildPing(
146 child_fds[content::ZygoteForkDelegate::kPIDOracleFDIndex]->get())); 146 child_fds[content::ZygoteForkDelegate::kPIDOracleFDIndex].get()));
147 147
148 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( 148 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
149 switches::kProcessChannelID, channel_id); 149 switches::kProcessChannelID, channel_id);
150 150
151 // Save the browser socket and close the rest. 151 // Save the browser socket and close the rest.
152 base::ScopedFD browser_fd( 152 base::ScopedFD browser_fd(
153 child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]->Pass()); 153 std::move(child_fds[content::ZygoteForkDelegate::kBrowserFDIndex]));
154 child_fds.clear(); 154 child_fds.clear();
155 155
156 BecomeNaClLoader( 156 BecomeNaClLoader(
157 browser_fd.Pass(), system_info, uses_nonsfi_mode, nacl_sandbox); 157 std::move(browser_fd), system_info, uses_nonsfi_mode, nacl_sandbox);
158 _exit(1); 158 _exit(1);
159 } 159 }
160 160
161 // Handle a fork request from the Zygote. 161 // Handle a fork request from the Zygote.
162 // Some of this code was lifted from 162 // Some of this code was lifted from
163 // content/browser/zygote_main_linux.cc:ForkWithRealPid() 163 // content/browser/zygote_main_linux.cc:ForkWithRealPid()
164 bool HandleForkRequest(ScopedVector<base::ScopedFD> child_fds, 164 bool HandleForkRequest(std::vector<base::ScopedFD> child_fds,
165 const NaClLoaderSystemInfo& system_info, 165 const NaClLoaderSystemInfo& system_info,
166 nacl::NaClSandbox* nacl_sandbox, 166 nacl::NaClSandbox* nacl_sandbox,
167 base::PickleIterator* input_iter, 167 base::PickleIterator* input_iter,
168 base::Pickle* output_pickle) { 168 base::Pickle* output_pickle) {
169 bool uses_nonsfi_mode; 169 bool uses_nonsfi_mode;
170 if (!input_iter->ReadBool(&uses_nonsfi_mode)) { 170 if (!input_iter->ReadBool(&uses_nonsfi_mode)) {
171 LOG(ERROR) << "Could not read uses_nonsfi_mode status"; 171 LOG(ERROR) << "Could not read uses_nonsfi_mode status";
172 return false; 172 return false;
173 } 173 }
174 174
(...skipping 25 matching lines...) Expand all
200 if (child_pid == 0) { 200 if (child_pid == 0) {
201 // Install termiantion signal handlers for nonsfi NaCl. The SFI NaCl runtime 201 // Install termiantion signal handlers for nonsfi NaCl. The SFI NaCl runtime
202 // will install signal handlers for SIGINT, SIGTERM, etc. so we do not need 202 // will install signal handlers for SIGINT, SIGTERM, etc. so we do not need
203 // to install termination signal handlers ourselves (in fact, it will crash 203 // to install termination signal handlers ourselves (in fact, it will crash
204 // if signal handlers for these are present). 204 // if signal handlers for these are present).
205 if (uses_nonsfi_mode && getpid() == 1) { 205 if (uses_nonsfi_mode && getpid() == 1) {
206 // Note that nonsfi NaCl may override some of these signal handlers, which 206 // Note that nonsfi NaCl may override some of these signal handlers, which
207 // is fine. 207 // is fine.
208 sandbox::NamespaceSandbox::InstallDefaultTerminationSignalHandlers(); 208 sandbox::NamespaceSandbox::InstallDefaultTerminationSignalHandlers();
209 } 209 }
210 ChildNaClLoaderInit(child_fds.Pass(), 210 ChildNaClLoaderInit(std::move(child_fds),
211 system_info, 211 system_info,
212 uses_nonsfi_mode, 212 uses_nonsfi_mode,
213 nacl_sandbox, 213 nacl_sandbox,
214 channel_id); 214 channel_id);
215 NOTREACHED(); 215 NOTREACHED();
216 } 216 }
217 217
218 // I am the parent. 218 // I am the parent.
219 // First, close the dummy_fd so the sandbox won't find me when 219 // First, close the dummy_fd so the sandbox won't find me when
220 // looking for the child's pid in /proc. Also close other fds. 220 // looking for the child's pid in /proc. Also close other fds.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 output_pickle->WriteInt(exit_code); 254 output_pickle->WriteInt(exit_code);
255 return true; 255 return true;
256 } 256 }
257 257
258 // Honor a command |command_type|. Eventual command parameters are 258 // Honor a command |command_type|. Eventual command parameters are
259 // available in |input_iter| and eventual file descriptors attached to 259 // available in |input_iter| and eventual file descriptors attached to
260 // the command are in |attached_fds|. 260 // the command are in |attached_fds|.
261 // Reply to the command on |reply_fds|. 261 // Reply to the command on |reply_fds|.
262 bool HonorRequestAndReply(int reply_fd, 262 bool HonorRequestAndReply(int reply_fd,
263 int command_type, 263 int command_type,
264 ScopedVector<base::ScopedFD> attached_fds, 264 std::vector<base::ScopedFD> attached_fds,
265 const NaClLoaderSystemInfo& system_info, 265 const NaClLoaderSystemInfo& system_info,
266 nacl::NaClSandbox* nacl_sandbox, 266 nacl::NaClSandbox* nacl_sandbox,
267 base::PickleIterator* input_iter) { 267 base::PickleIterator* input_iter) {
268 base::Pickle write_pickle; 268 base::Pickle write_pickle;
269 bool have_to_reply = false; 269 bool have_to_reply = false;
270 // Commands must write anything to send back to |write_pickle|. 270 // Commands must write anything to send back to |write_pickle|.
271 switch (command_type) { 271 switch (command_type) {
272 case nacl::kNaClForkRequest: 272 case nacl::kNaClForkRequest:
273 have_to_reply = HandleForkRequest(attached_fds.Pass(), 273 have_to_reply = HandleForkRequest(std::move(attached_fds),
274 system_info, 274 system_info,
275 nacl_sandbox, 275 nacl_sandbox,
276 input_iter, 276 input_iter,
277 &write_pickle); 277 &write_pickle);
278 break; 278 break;
279 case nacl::kNaClGetTerminationStatusRequest: 279 case nacl::kNaClGetTerminationStatusRequest:
280 have_to_reply = 280 have_to_reply =
281 HandleGetTerminationStatusRequest(input_iter, &write_pickle); 281 HandleGetTerminationStatusRequest(input_iter, &write_pickle);
282 break; 282 break;
283 default: 283 default:
284 LOG(ERROR) << "Unsupported command from Zygote"; 284 LOG(ERROR) << "Unsupported command from Zygote";
285 return false; 285 return false;
286 } 286 }
287 if (!have_to_reply) 287 if (!have_to_reply)
288 return false; 288 return false;
289 const std::vector<int> empty; // We never send file descriptors back. 289 const std::vector<int> empty; // We never send file descriptors back.
290 if (!base::UnixDomainSocket::SendMsg(reply_fd, write_pickle.data(), 290 if (!base::UnixDomainSocket::SendMsg(reply_fd, write_pickle.data(),
291 write_pickle.size(), empty)) { 291 write_pickle.size(), empty)) {
292 LOG(ERROR) << "*** send() to zygote failed"; 292 LOG(ERROR) << "*** send() to zygote failed";
293 return false; 293 return false;
294 } 294 }
295 return true; 295 return true;
296 } 296 }
297 297
298 // Read a request from the Zygote from |zygote_ipc_fd| and handle it. 298 // Read a request from the Zygote from |zygote_ipc_fd| and handle it.
299 // Die on EOF from |zygote_ipc_fd|. 299 // Die on EOF from |zygote_ipc_fd|.
300 bool HandleZygoteRequest(int zygote_ipc_fd, 300 bool HandleZygoteRequest(int zygote_ipc_fd,
301 const NaClLoaderSystemInfo& system_info, 301 const NaClLoaderSystemInfo& system_info,
302 nacl::NaClSandbox* nacl_sandbox) { 302 nacl::NaClSandbox* nacl_sandbox) {
303 ScopedVector<base::ScopedFD> fds; 303 std::vector<base::ScopedFD> fds;
304 char buf[kNaClMaxIPCMessageLength]; 304 char buf[kNaClMaxIPCMessageLength];
305 const ssize_t msglen = base::UnixDomainSocket::RecvMsg(zygote_ipc_fd, 305 const ssize_t msglen = base::UnixDomainSocket::RecvMsg(zygote_ipc_fd,
306 &buf, sizeof(buf), &fds); 306 &buf, sizeof(buf), &fds);
307 // If the Zygote has started handling requests, we should be sandboxed via 307 // If the Zygote has started handling requests, we should be sandboxed via
308 // the setuid sandbox. 308 // the setuid sandbox.
309 if (!nacl_sandbox->layer_one_enabled()) { 309 if (!nacl_sandbox->layer_one_enabled()) {
310 LOG(ERROR) << "NaCl helper process running without a sandbox!\n" 310 LOG(ERROR) << "NaCl helper process running without a sandbox!\n"
311 << "Most likely you need to configure your SUID sandbox " 311 << "Most likely you need to configure your SUID sandbox "
312 << "correctly"; 312 << "correctly";
313 } 313 }
314 if (msglen == 0 || (msglen == -1 && errno == ECONNRESET)) { 314 if (msglen == 0 || (msglen == -1 && errno == ECONNRESET)) {
315 // EOF from the browser. Goodbye! 315 // EOF from the browser. Goodbye!
316 _exit(0); 316 _exit(0);
317 } 317 }
318 if (msglen < 0) { 318 if (msglen < 0) {
319 PLOG(ERROR) << "nacl_helper: receive from zygote failed"; 319 PLOG(ERROR) << "nacl_helper: receive from zygote failed";
320 return false; 320 return false;
321 } 321 }
322 322
323 base::Pickle read_pickle(buf, msglen); 323 base::Pickle read_pickle(buf, msglen);
324 base::PickleIterator read_iter(read_pickle); 324 base::PickleIterator read_iter(read_pickle);
325 int command_type; 325 int command_type;
326 if (!read_iter.ReadInt(&command_type)) { 326 if (!read_iter.ReadInt(&command_type)) {
327 LOG(ERROR) << "Unable to read command from Zygote"; 327 LOG(ERROR) << "Unable to read command from Zygote";
328 return false; 328 return false;
329 } 329 }
330 return HonorRequestAndReply(zygote_ipc_fd, 330 return HonorRequestAndReply(zygote_ipc_fd,
331 command_type, 331 command_type,
332 fds.Pass(), 332 std::move(fds),
333 system_info, 333 system_info,
334 nacl_sandbox, 334 nacl_sandbox,
335 &read_iter); 335 &read_iter);
336 } 336 }
337 337
338 #if !defined(OS_NACL_NONSFI) 338 #if !defined(OS_NACL_NONSFI)
339 static const char kNaClHelperReservedAtZero[] = "reserved_at_zero"; 339 static const char kNaClHelperReservedAtZero[] = "reserved_at_zero";
340 static const char kNaClHelperRDebug[] = "r_debug"; 340 static const char kNaClHelperRDebug[] = "r_debug";
341 341
342 // Since we were started by nacl_helper_bootstrap rather than in the 342 // Since we were started by nacl_helper_bootstrap rather than in the
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 // Now handle requests from the Zygote. 470 // Now handle requests from the Zygote.
471 while (true) { 471 while (true) {
472 bool request_handled = HandleZygoteRequest( 472 bool request_handled = HandleZygoteRequest(
473 kNaClZygoteDescriptor, system_info, nacl_sandbox.get()); 473 kNaClZygoteDescriptor, system_info, nacl_sandbox.get());
474 // Do not turn this into a CHECK() without thinking about robustness 474 // Do not turn this into a CHECK() without thinking about robustness
475 // against malicious IPC requests. 475 // against malicious IPC requests.
476 DCHECK(request_handled); 476 DCHECK(request_handled);
477 } 477 }
478 NOTREACHED(); 478 NOTREACHED();
479 } 479 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698