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

Side by Side Diff: content/browser/zygote_host/zygote_host_impl_linux.cc

Issue 269543014: Use RecvMsgWithPid to find real PID for zygote children (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Restore error handling code paths Created 6 years, 7 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "content/browser/zygote_host/zygote_host_impl_linux.h" 5 #include "content/browser/zygote_host/zygote_host_impl_linux.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 #include <sys/socket.h> 8 #include <sys/socket.h>
9 #include <sys/stat.h> 9 #include <sys/stat.h>
10 #include <sys/types.h> 10 #include <sys/types.h>
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 return HANDLE_EINTR(read(control_fd_, buf, buf_len)); 287 return HANDLE_EINTR(read(control_fd_, buf, buf_len));
288 } 288 }
289 289
290 pid_t ZygoteHostImpl::ForkRequest( 290 pid_t ZygoteHostImpl::ForkRequest(
291 const std::vector<std::string>& argv, 291 const std::vector<std::string>& argv,
292 const std::vector<FileDescriptorInfo>& mapping, 292 const std::vector<FileDescriptorInfo>& mapping,
293 const std::string& process_type) { 293 const std::string& process_type) {
294 DCHECK(init_); 294 DCHECK(init_);
295 Pickle pickle; 295 Pickle pickle;
296 296
297 int raw_socks[2];
298 PCHECK(0 == socketpair(AF_UNIX, SOCK_SEQPACKET, 0, raw_socks));
299 base::ScopedFD my_sock(raw_socks[0]);
300 base::ScopedFD peer_sock(raw_socks[1]);
301 CHECK(UnixDomainSocket::EnableReceiveProcessId(my_sock.get()));
302
297 pickle.WriteInt(kZygoteCommandFork); 303 pickle.WriteInt(kZygoteCommandFork);
298 pickle.WriteString(process_type); 304 pickle.WriteString(process_type);
299 pickle.WriteInt(argv.size()); 305 pickle.WriteInt(argv.size());
300 for (std::vector<std::string>::const_iterator 306 for (std::vector<std::string>::const_iterator
301 i = argv.begin(); i != argv.end(); ++i) 307 i = argv.begin(); i != argv.end(); ++i)
302 pickle.WriteString(*i); 308 pickle.WriteString(*i);
303 309
304 pickle.WriteInt(mapping.size()); 310 // Fork requests contain one file descriptor for the PID oracle, and one
311 // more for each file descriptor mapping for the child process.
312 const size_t num_fds_to_send = 1 + mapping.size();
313 pickle.WriteInt(num_fds_to_send);
305 314
306 std::vector<int> fds; 315 std::vector<int> fds;
307 // Scoped pointers cannot be stored in containers, so we have to use a 316 ScopedVector<base::ScopedFD> autoclose_fds;
308 // linked_ptr. 317
309 std::vector<linked_ptr<base::ScopedFD> > autodelete_fds; 318 // First FD to send is peer_sock.
319 fds.push_back(peer_sock.get());
320 autoclose_fds.push_back(new base::ScopedFD(peer_sock.Pass()));
321
322 // The rest come from mapping.
310 for (std::vector<FileDescriptorInfo>::const_iterator 323 for (std::vector<FileDescriptorInfo>::const_iterator
311 i = mapping.begin(); i != mapping.end(); ++i) { 324 i = mapping.begin(); i != mapping.end(); ++i) {
312 pickle.WriteUInt32(i->id); 325 pickle.WriteUInt32(i->id);
313 fds.push_back(i->fd.fd); 326 fds.push_back(i->fd.fd);
314 if (i->fd.auto_close) { 327 if (i->fd.auto_close) {
315 // Auto-close means we need to close the FDs after they have been passed 328 // Auto-close means we need to close the FDs after they have been passed
316 // to the other process. 329 // to the other process.
317 linked_ptr<base::ScopedFD> ptr(new base::ScopedFD(fds.back())); 330 autoclose_fds.push_back(new base::ScopedFD(i->fd.fd));
318 autodelete_fds.push_back(ptr);
319 } 331 }
320 } 332 }
321 333
334 // Sanity check that we've populated |fds| correctly.
335 DCHECK_EQ(num_fds_to_send, fds.size());
336
322 pid_t pid; 337 pid_t pid;
323 { 338 {
324 base::AutoLock lock(control_lock_); 339 base::AutoLock lock(control_lock_);
325 if (!SendMessage(pickle, &fds)) 340 if (!SendMessage(pickle, &fds))
326 return base::kNullProcessHandle; 341 return base::kNullProcessHandle;
342 autoclose_fds.clear();
343
344 {
345 char buf[sizeof(kZygoteChildPingMessage) + 1];
346 ScopedVector<base::ScopedFD> recv_fds;
347 base::ProcessId real_pid;
348
349 ssize_t n = UnixDomainSocket::RecvMsgWithPid(
350 my_sock.get(), buf, sizeof(buf), &recv_fds, &real_pid);
351 if (n != sizeof(kZygoteChildPingMessage) ||
352 0 != memcmp(buf,
353 kZygoteChildPingMessage,
354 sizeof(kZygoteChildPingMessage))) {
355 // Zygote children should still be trustworthy when they're supposed to
356 // ping us, so something's broken if we don't receive a valid ping.
357 LOG(ERROR) << "Did not receive ping from zygote child";
358 NOTREACHED();
359 real_pid = -1;
360 }
361 my_sock.reset();
362
363 // Always send PID back to zygote.
364 Pickle pid_pickle;
365 pid_pickle.WriteInt(kZygoteCommandForkRealPID);
366 pid_pickle.WriteInt(real_pid);
367 if (!SendMessage(pid_pickle, NULL))
368 return base::kNullProcessHandle;
369 }
327 370
328 // Read the reply, which pickles the PID and an optional UMA enumeration. 371 // Read the reply, which pickles the PID and an optional UMA enumeration.
329 static const unsigned kMaxReplyLength = 2048; 372 static const unsigned kMaxReplyLength = 2048;
330 char buf[kMaxReplyLength]; 373 char buf[kMaxReplyLength];
331 const ssize_t len = ReadReply(buf, sizeof(buf)); 374 const ssize_t len = ReadReply(buf, sizeof(buf));
332 375
333 Pickle reply_pickle(buf, len); 376 Pickle reply_pickle(buf, len);
334 PickleIterator iter(reply_pickle); 377 PickleIterator iter(reply_pickle);
335 if (len <= 0 || !reply_pickle.ReadInt(&iter, &pid)) 378 if (len <= 0 || !reply_pickle.ReadInt(&iter, &pid))
336 return base::kNullProcessHandle; 379 return base::kNullProcessHandle;
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 return RenderSandboxHostLinux::GetInstance()->pid(); 563 return RenderSandboxHostLinux::GetInstance()->pid();
521 } 564 }
522 565
523 int ZygoteHostImpl::GetSandboxStatus() const { 566 int ZygoteHostImpl::GetSandboxStatus() const {
524 if (have_read_sandbox_status_word_) 567 if (have_read_sandbox_status_word_)
525 return sandbox_status_; 568 return sandbox_status_;
526 return 0; 569 return 0;
527 } 570 }
528 571
529 } // namespace content 572 } // namespace content
OLDNEW
« no previous file with comments | « components/nacl/loader/nacl_helper_linux.cc ('k') | content/common/child_process_sandbox_support_impl_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698