1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 // Copyright (c) 2008 The Chromium Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6 
7 #include "chrome/common/ipc_channel_posix.h"
8 
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <limits.h>
12 #if defined(OS_MACOSX) || defined(OS_NETBSD)
13 #  include <sched.h>
14 #endif
15 #include <stddef.h>
16 #include <unistd.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <sys/stat.h>
20 #include <sys/un.h>
21 #include <sys/uio.h>
22 
23 #include <string>
24 #include <map>
25 
26 #include "base/command_line.h"
27 #include "base/eintr_wrapper.h"
28 #include "base/logging.h"
29 #include "base/process_util.h"
30 #include "base/string_util.h"
31 #include "chrome/common/chrome_switches.h"
32 #include "chrome/common/file_descriptor_set_posix.h"
33 #include "chrome/common/ipc_channel_utils.h"
34 #include "chrome/common/ipc_message_utils.h"
35 #include "mozilla/ipc/Endpoint.h"
36 #include "mozilla/ipc/ProtocolUtils.h"
37 #include "mozilla/Atomics.h"
38 #include "mozilla/StaticMutex.h"
39 #include "mozilla/UniquePtr.h"
40 #include "mozilla/Unused.h"
41 
42 #ifdef FUZZING
43 #  include "mozilla/ipc/Faulty.h"
44 #endif
45 
46 // Use OS specific iovec array limit where it's possible.
47 #if defined(IOV_MAX)
48 static const size_t kMaxIOVecSize = IOV_MAX;
49 #elif defined(ANDROID)
50 static const size_t kMaxIOVecSize = 256;
51 #else
52 static const size_t kMaxIOVecSize = 16;
53 #endif
54 
55 using namespace mozilla::ipc;
56 
57 namespace IPC {
58 
59 // IPC channels on Windows use named pipes (CreateNamedPipe()) with
60 // channel ids as the pipe names.  Channels on POSIX use anonymous
61 // Unix domain sockets created via socketpair() as pipes.  These don't
62 // quite line up.
63 //
64 // When creating a child subprocess, the parent side of the fork
65 // arranges it such that the initial control channel ends up on the
66 // magic file descriptor gClientChannelFd in the child.  Future
67 // connections (file descriptors) can then be passed via that
68 // connection via sendmsg().
69 //
70 // On Android, child processes are created as a service instead of
71 // forking the parent process. The Android Binder service is used to
72 // transport the IPC channel file descriptor to the child process.
73 // So rather than re-mapping the file descriptor to a known value,
74 // the received channel file descriptor is set by calling
75 // SetClientChannelFd before gecko has been initialized and started
76 // in the child process.
77 
78 //------------------------------------------------------------------------------
79 namespace {
80 
81 // This is the file descriptor number that a client process expects to find its
82 // IPC socket.
83 static int gClientChannelFd =
84 #if defined(MOZ_WIDGET_ANDROID)
85     // On android the fd is set at the time of child creation.
86     -1
87 #else
88     3
89 #endif  // defined(MOZ_WIDGET_ANDROID)
90     ;
91 
92 //------------------------------------------------------------------------------
93 const size_t kMaxPipeNameLength = sizeof(((sockaddr_un*)0)->sun_path);
94 
SetCloseOnExec(int fd)95 bool SetCloseOnExec(int fd) {
96   int flags = fcntl(fd, F_GETFD);
97   if (flags == -1) return false;
98 
99   flags |= FD_CLOEXEC;
100   if (fcntl(fd, F_SETFD, flags) == -1) return false;
101 
102   return true;
103 }
104 
ErrorIsBrokenPipe(int err)105 bool ErrorIsBrokenPipe(int err) { return err == EPIPE || err == ECONNRESET; }
106 
107 // Some Android ARM64 devices appear to have a bug where sendmsg
108 // sometimes returns 0xFFFFFFFF, which we're assuming is a -1 that was
109 // incorrectly truncated to 32-bit and then zero-extended.
110 // See bug 1660826 for details.
111 //
112 // This is a workaround to detect that value and replace it with -1
113 // (and check that there really was an error), because the largest
114 // amount we'll ever write is Channel::kMaximumMessageSize (256MiB).
115 //
116 // The workaround is also enabled on x86_64 Android on debug builds,
117 // although the bug isn't known to manifest there, so that there will
118 // be some CI coverage of this code.
119 
corrected_sendmsg(int socket,const struct msghdr * message,int flags)120 static inline ssize_t corrected_sendmsg(int socket,
121                                         const struct msghdr* message,
122                                         int flags) {
123 #if defined(ANDROID) && \
124     (defined(__aarch64__) || (defined(DEBUG) && defined(__x86_64__)))
125   static constexpr auto kBadValue = static_cast<ssize_t>(0xFFFFFFFF);
126   static_assert(kBadValue > 0);
127 
128 #  ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
129   errno = 0;
130 #  endif
131   ssize_t bytes_written = sendmsg(socket, message, flags);
132   if (bytes_written == kBadValue) {
133     MOZ_DIAGNOSTIC_ASSERT(errno != 0);
134     bytes_written = -1;
135   }
136   MOZ_DIAGNOSTIC_ASSERT(bytes_written < kBadValue);
137   return bytes_written;
138 #else
139   return sendmsg(socket, message, flags);
140 #endif
141 }
142 
143 }  // namespace
144 //------------------------------------------------------------------------------
145 
146 #if defined(MOZ_WIDGET_ANDROID)
SetClientChannelFd(int fd)147 void Channel::SetClientChannelFd(int fd) { gClientChannelFd = fd; }
148 #endif  // defined(MOZ_WIDGET_ANDROID)
149 
ChannelImpl(const ChannelId & channel_id,Mode mode,Listener * listener)150 Channel::ChannelImpl::ChannelImpl(const ChannelId& channel_id, Mode mode,
151                                   Listener* listener)
152     : factory_(this) {
153   Init(mode, listener);
154 
155   if (!CreatePipe(mode)) {
156     CHROMIUM_LOG(WARNING) << "Unable to create pipe in "
157                           << (mode == MODE_SERVER ? "server" : "client")
158                           << " mode error(" << strerror(errno) << ").";
159     closed_ = true;
160     return;
161   }
162 
163   EnqueueHelloMessage();
164 }
165 
ChannelImpl(int fd,Mode mode,Listener * listener)166 Channel::ChannelImpl::ChannelImpl(int fd, Mode mode, Listener* listener)
167     : factory_(this) {
168   Init(mode, listener);
169   SetPipe(fd);
170   waiting_connect_ = (MODE_SERVER == mode);
171 
172   EnqueueHelloMessage();
173 }
174 
SetPipe(int fd)175 void Channel::ChannelImpl::SetPipe(int fd) {
176   pipe_ = fd;
177   pipe_buf_len_ = 0;
178   if (fd >= 0) {
179     int buf_len;
180     socklen_t optlen = sizeof(buf_len);
181     if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buf_len, &optlen) != 0) {
182       CHROMIUM_LOG(WARNING)
183           << "Unable to determine pipe buffer size: " << strerror(errno);
184       return;
185     }
186     CHECK(optlen == sizeof(buf_len));
187     CHECK(buf_len > 0);
188     pipe_buf_len_ = static_cast<unsigned>(buf_len);
189   }
190 }
191 
PipeBufHasSpaceAfter(size_t already_written)192 bool Channel::ChannelImpl::PipeBufHasSpaceAfter(size_t already_written) {
193   // If the OS didn't tell us the buffer size for some reason, then
194   // don't apply this limitation on the amount we try to write.
195   return pipe_buf_len_ == 0 ||
196          static_cast<size_t>(pipe_buf_len_) > already_written;
197 }
198 
Init(Mode mode,Listener * listener)199 void Channel::ChannelImpl::Init(Mode mode, Listener* listener) {
200   // Verify that we fit in a "quantum-spaced" jemalloc bucket.
201   static_assert(sizeof(*this) <= 512, "Exceeded expected size class");
202 
203   DCHECK(kControlBufferHeaderSize >= CMSG_SPACE(0));
204 
205   mode_ = mode;
206   is_blocked_on_write_ = false;
207   partial_write_iter_.reset();
208   input_buf_offset_ = 0;
209   input_buf_ = mozilla::MakeUnique<char[]>(Channel::kReadBufferSize);
210   input_cmsg_buf_ = mozilla::MakeUnique<char[]>(kControlBufferSize);
211   server_listen_pipe_ = -1;
212   SetPipe(-1);
213   client_pipe_ = -1;
214   listener_ = listener;
215   waiting_connect_ = true;
216   processing_incoming_ = false;
217   closed_ = false;
218 #if defined(OS_MACOSX)
219   last_pending_fd_id_ = 0;
220 #endif
221   output_queue_length_ = 0;
222 }
223 
CreatePipe(Mode mode)224 bool Channel::ChannelImpl::CreatePipe(Mode mode) {
225   DCHECK(server_listen_pipe_ == -1 && pipe_ == -1);
226 
227   if (mode == MODE_SERVER) {
228     // socketpair()
229     int pipe_fds[2];
230     if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) {
231       mozilla::ipc::AnnotateCrashReportWithErrno(
232           CrashReporter::Annotation::IpcCreatePipeSocketPairErrno, errno);
233       return false;
234     }
235     // Set both ends to be non-blocking.
236     if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 ||
237         fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) {
238       mozilla::ipc::AnnotateCrashReportWithErrno(
239           CrashReporter::Annotation::IpcCreatePipeFcntlErrno, errno);
240       IGNORE_EINTR(close(pipe_fds[0]));
241       IGNORE_EINTR(close(pipe_fds[1]));
242       return false;
243     }
244 
245     if (!SetCloseOnExec(pipe_fds[0]) || !SetCloseOnExec(pipe_fds[1])) {
246       mozilla::ipc::AnnotateCrashReportWithErrno(
247           CrashReporter::Annotation::IpcCreatePipeCloExecErrno, errno);
248       IGNORE_EINTR(close(pipe_fds[0]));
249       IGNORE_EINTR(close(pipe_fds[1]));
250       return false;
251     }
252 
253     SetPipe(pipe_fds[0]);
254     client_pipe_ = pipe_fds[1];
255   } else {
256     static mozilla::Atomic<bool> consumed(false);
257     CHECK(!consumed.exchange(true))
258     << "child process main channel can be created only once";
259     SetPipe(gClientChannelFd);
260     waiting_connect_ = false;
261   }
262 
263   return true;
264 }
265 
266 /**
267  * Reset the file descriptor for communication with the peer.
268  */
ResetFileDescriptor(int fd)269 void Channel::ChannelImpl::ResetFileDescriptor(int fd) {
270   NS_ASSERTION(fd > 0 && fd == pipe_, "Invalid file descriptor");
271 
272   EnqueueHelloMessage();
273 }
274 
EnqueueHelloMessage()275 bool Channel::ChannelImpl::EnqueueHelloMessage() {
276   mozilla::UniquePtr<Message> msg(
277       new Message(MSG_ROUTING_NONE, HELLO_MESSAGE_TYPE));
278   if (!msg->WriteInt(base::GetCurrentProcId())) {
279     Close();
280     return false;
281   }
282 
283   OutputQueuePush(std::move(msg));
284   return true;
285 }
286 
Connect()287 bool Channel::ChannelImpl::Connect() {
288   if (pipe_ == -1) {
289     return false;
290   }
291 
292   MessageLoopForIO::current()->WatchFileDescriptor(
293       pipe_, true, MessageLoopForIO::WATCH_READ, &read_watcher_, this);
294   waiting_connect_ = false;
295 
296   if (!waiting_connect_) return ProcessOutgoingMessages();
297   return true;
298 }
299 
ProcessIncomingMessages()300 bool Channel::ChannelImpl::ProcessIncomingMessages() {
301   struct msghdr msg = {0};
302   struct iovec iov;
303 
304   msg.msg_iov = &iov;
305   msg.msg_iovlen = 1;
306   msg.msg_control = input_cmsg_buf_.get();
307 
308   for (;;) {
309     msg.msg_controllen = kControlBufferSize;
310 
311     if (pipe_ == -1) return false;
312 
313     // In some cases the beginning of a message will be stored in input_buf_. We
314     // don't want to overwrite that, so we store the new data after it.
315     iov.iov_base = input_buf_.get() + input_buf_offset_;
316     iov.iov_len = Channel::kReadBufferSize - input_buf_offset_;
317 
318     // Read from pipe.
319     // recvmsg() returns 0 if the connection has closed or EAGAIN if no data
320     // is waiting on the pipe.
321     ssize_t bytes_read = HANDLE_EINTR(recvmsg(pipe_, &msg, MSG_DONTWAIT));
322 
323     if (bytes_read < 0) {
324       if (errno == EAGAIN) {
325         return true;
326       } else {
327         if (!ErrorIsBrokenPipe(errno)) {
328           CHROMIUM_LOG(ERROR)
329               << "pipe error (fd " << pipe_ << "): " << strerror(errno);
330         }
331         return false;
332       }
333     } else if (bytes_read == 0) {
334       // The pipe has closed...
335       Close();
336       return false;
337     }
338     DCHECK(bytes_read);
339 
340     // a pointer to an array of |num_wire_fds| file descriptors from the read
341     const int* wire_fds = NULL;
342     unsigned num_wire_fds = 0;
343 
344     // walk the list of control messages and, if we find an array of file
345     // descriptors, save a pointer to the array
346 
347     // This next if statement is to work around an OSX issue where
348     // CMSG_FIRSTHDR will return non-NULL in the case that controllen == 0.
349     // Here's a test case:
350     //
351     // int main() {
352     // struct msghdr msg;
353     //   msg.msg_control = &msg;
354     //   msg.msg_controllen = 0;
355     //   if (CMSG_FIRSTHDR(&msg))
356     //     printf("Bug found!\n");
357     // }
358     if (msg.msg_controllen > 0) {
359       // On OSX, CMSG_FIRSTHDR doesn't handle the case where controllen is 0
360       // and will return a pointer into nowhere.
361       for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); cmsg;
362            cmsg = CMSG_NXTHDR(&msg, cmsg)) {
363         if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
364           const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0);
365           DCHECK(payload_len % sizeof(int) == 0);
366           wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
367           num_wire_fds = payload_len / 4;
368 
369           if (msg.msg_flags & MSG_CTRUNC) {
370             CHROMIUM_LOG(ERROR)
371                 << "SCM_RIGHTS message was truncated"
372                 << " cmsg_len:" << cmsg->cmsg_len << " fd:" << pipe_;
373             for (unsigned i = 0; i < num_wire_fds; ++i)
374               IGNORE_EINTR(close(wire_fds[i]));
375             return false;
376           }
377           break;
378         }
379       }
380     }
381 
382     // Process messages from input buffer.
383     const char* p = input_buf_.get();
384     const char* end = input_buf_.get() + input_buf_offset_ + bytes_read;
385 
386     // A pointer to an array of |num_fds| file descriptors which includes any
387     // fds that have spilled over from a previous read.
388     const int* fds;
389     unsigned num_fds;
390     unsigned fds_i = 0;  // the index of the first unused descriptor
391 
392     if (input_overflow_fds_.empty()) {
393       fds = wire_fds;
394       num_fds = num_wire_fds;
395     } else {
396       // This code may look like a no-op in the case where
397       // num_wire_fds == 0, but in fact:
398       //
399       // 1. wire_fds will be nullptr, so passing it to memcpy is
400       // undefined behavior according to the C standard, even though
401       // the memcpy length is 0.
402       //
403       // 2. prev_size will be an out-of-bounds index for
404       // input_overflow_fds_; this is undefined behavior according to
405       // the C++ standard, even though the element only has its
406       // pointer taken and isn't accessed (and the corresponding
407       // operation on a C array would be defined).
408       //
409       // UBSan makes #1 a fatal error, and assertions in libstdc++ do
410       // the same for #2 if enabled.
411       if (num_wire_fds > 0) {
412         const size_t prev_size = input_overflow_fds_.size();
413         input_overflow_fds_.resize(prev_size + num_wire_fds);
414         memcpy(&input_overflow_fds_[prev_size], wire_fds,
415                num_wire_fds * sizeof(int));
416       }
417       fds = &input_overflow_fds_[0];
418       num_fds = input_overflow_fds_.size();
419     }
420 
421     // The data for the message we're currently reading consists of any data
422     // stored in incoming_message_ followed by data in input_buf_ (followed by
423     // other messages).
424 
425     while (p < end) {
426       // Try to figure out how big the message is. Size is 0 if we haven't read
427       // enough of the header to know the size.
428       uint32_t message_length = 0;
429       if (incoming_message_.isSome()) {
430         message_length = incoming_message_.ref().size();
431       } else {
432         message_length = Message::MessageSize(p, end);
433       }
434 
435       if (!message_length) {
436         // We haven't seen the full message header.
437         MOZ_ASSERT(incoming_message_.isNothing());
438 
439         // Move everything we have to the start of the buffer. We'll finish
440         // reading this message when we get more data. For now we leave it in
441         // input_buf_.
442         memmove(input_buf_.get(), p, end - p);
443         input_buf_offset_ = end - p;
444 
445         break;
446       }
447 
448       input_buf_offset_ = 0;
449 
450       bool partial;
451       if (incoming_message_.isSome()) {
452         // We already have some data for this message stored in
453         // incoming_message_. We want to append the new data there.
454         Message& m = incoming_message_.ref();
455 
456         // How much data from this message remains to be added to
457         // incoming_message_?
458         MOZ_DIAGNOSTIC_ASSERT(message_length > m.CurrentSize());
459         uint32_t remaining = message_length - m.CurrentSize();
460 
461         // How much data from this message is stored in input_buf_?
462         uint32_t in_buf = std::min(remaining, uint32_t(end - p));
463 
464         m.InputBytes(p, in_buf);
465         p += in_buf;
466 
467         // Are we done reading this message?
468         partial = in_buf != remaining;
469       } else {
470         // How much data from this message is stored in input_buf_?
471         uint32_t in_buf = std::min(message_length, uint32_t(end - p));
472 
473         incoming_message_.emplace(p, in_buf);
474         p += in_buf;
475 
476         // Are we done reading this message?
477         partial = in_buf != message_length;
478       }
479 
480       if (partial) {
481         break;
482       }
483 
484       Message& m = incoming_message_.ref();
485 
486       if (m.header()->num_fds) {
487         // the message has file descriptors
488         const char* error = NULL;
489         if (m.header()->num_fds > num_fds - fds_i) {
490           // the message has been completely received, but we didn't get
491           // enough file descriptors.
492           error = "Message needs unreceived descriptors";
493         }
494 
495         if (m.header()->num_fds >
496             FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE) {
497           // There are too many descriptors in this message
498           error = "Message requires an excessive number of descriptors";
499         }
500 
501         if (error) {
502           CHROMIUM_LOG(WARNING)
503               << error << " channel:" << this << " message-type:" << m.type()
504               << " header()->num_fds:" << m.header()->num_fds
505               << " num_fds:" << num_fds << " fds_i:" << fds_i;
506           // close the existing file descriptors so that we don't leak them
507           for (unsigned i = fds_i; i < num_fds; ++i)
508             IGNORE_EINTR(close(fds[i]));
509           input_overflow_fds_.clear();
510           // abort the connection
511           return false;
512         }
513 
514 #if defined(OS_MACOSX)
515         // Send a message to the other side, indicating that we are now
516         // responsible for closing the descriptor.
517         auto fdAck = mozilla::MakeUnique<Message>(MSG_ROUTING_NONE,
518                                                   RECEIVED_FDS_MESSAGE_TYPE);
519         DCHECK(m.fd_cookie() != 0);
520         fdAck->set_fd_cookie(m.fd_cookie());
521         OutputQueuePush(std::move(fdAck));
522 #endif
523 
524         m.file_descriptor_set()->SetDescriptors(&fds[fds_i],
525                                                 m.header()->num_fds);
526         fds_i += m.header()->num_fds;
527       }
528 
529       // Note: We set other_pid_ below when we receive a Hello message (which
530       // has no routing ID), but we only emit a profiler marker for messages
531       // with a routing ID, so there's no conflict here.
532       AddIPCProfilerMarker(m, other_pid_, MessageDirection::eReceiving,
533                            MessagePhase::TransferEnd);
534 
535 #ifdef IPC_MESSAGE_DEBUG_EXTRA
536       DLOG(INFO) << "received message on channel @" << this << " with type "
537                  << m.type();
538 #endif
539 
540       if (m.routing_id() == MSG_ROUTING_NONE &&
541           m.type() == HELLO_MESSAGE_TYPE) {
542         // The Hello message contains only the process id.
543         other_pid_ = MessageIterator(m).NextInt();
544         listener_->OnChannelConnected(other_pid_);
545 #if defined(OS_MACOSX)
546       } else if (m.routing_id() == MSG_ROUTING_NONE &&
547                  m.type() == RECEIVED_FDS_MESSAGE_TYPE) {
548         DCHECK(m.fd_cookie() != 0);
549         CloseDescriptors(m.fd_cookie());
550 #endif
551       } else {
552         mozilla::LogIPCMessage::Run run(&m);
553         listener_->OnMessageReceived(std::move(m));
554       }
555 
556       incoming_message_.reset();
557     }
558 
559     input_overflow_fds_ = std::vector<int>(&fds[fds_i], &fds[num_fds]);
560 
561     // When the input data buffer is empty, the overflow fds should be too. If
562     // this is not the case, we probably have a rogue renderer which is trying
563     // to fill our descriptor table.
564     if (incoming_message_.isNothing() && input_buf_offset_ == 0 &&
565         !input_overflow_fds_.empty()) {
566       // We close these descriptors in Close()
567       return false;
568     }
569   }
570 
571   return true;
572 }
573 
ProcessOutgoingMessages()574 bool Channel::ChannelImpl::ProcessOutgoingMessages() {
575   DCHECK(!waiting_connect_);  // Why are we trying to send messages if there's
576                               // no connection?
577   is_blocked_on_write_ = false;
578 
579   if (output_queue_.IsEmpty()) return true;
580 
581   if (pipe_ == -1) return false;
582 
583   // Write out all the messages we can till the write blocks or there are no
584   // more outgoing messages.
585   while (!output_queue_.IsEmpty()) {
586 #ifdef FUZZING
587     mozilla::ipc::Faulty::instance().MaybeCollectAndClosePipe(pipe_);
588 #endif
589     Message* msg = output_queue_.FirstElement().get();
590 
591     struct msghdr msgh = {0};
592 
593     static const int tmp =
594         CMSG_SPACE(sizeof(int[FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE]));
595     char buf[tmp];
596 
597     if (partial_write_iter_.isNothing()) {
598       Pickle::BufferList::IterImpl iter(msg->Buffers());
599       MOZ_DIAGNOSTIC_ASSERT(!iter.Done(), "empty message");
600       partial_write_iter_.emplace(iter);
601     }
602 
603     if (partial_write_iter_.ref().Done()) {
604       MOZ_DIAGNOSTIC_ASSERT(false, "partial_write_iter_ should not be null");
605       // report a send error to our caller, which will close the channel.
606       return false;
607     }
608 
609     if (partial_write_iter_.value().Data() == msg->Buffers().Start()) {
610       AddIPCProfilerMarker(*msg, other_pid_, MessageDirection::eSending,
611                            MessagePhase::TransferStart);
612 
613       if (!msg->file_descriptor_set()->empty()) {
614         // This is the first chunk of a message which has descriptors to send
615         struct cmsghdr* cmsg;
616         const unsigned num_fds = msg->file_descriptor_set()->size();
617 
618         if (num_fds > FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE) {
619           MOZ_DIAGNOSTIC_ASSERT(false, "Too many file descriptors!");
620           CHROMIUM_LOG(FATAL) << "Too many file descriptors!";
621           // This should not be reached.
622           return false;
623         }
624 
625         msgh.msg_control = buf;
626         msgh.msg_controllen = CMSG_SPACE(sizeof(int) * num_fds);
627         cmsg = CMSG_FIRSTHDR(&msgh);
628         cmsg->cmsg_level = SOL_SOCKET;
629         cmsg->cmsg_type = SCM_RIGHTS;
630         cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fds);
631         msg->file_descriptor_set()->GetDescriptors(
632             reinterpret_cast<int*>(CMSG_DATA(cmsg)));
633         msgh.msg_controllen = cmsg->cmsg_len;
634 
635         msg->header()->num_fds = num_fds;
636 #if defined(OS_MACOSX)
637         msg->set_fd_cookie(++last_pending_fd_id_);
638 #endif
639       }
640     }
641 
642     struct iovec iov[kMaxIOVecSize];
643     size_t iov_count = 0;
644     size_t amt_to_write = 0;
645 
646     // How much of this message have we written so far?
647     Pickle::BufferList::IterImpl iter = partial_write_iter_.value();
648 
649     // Store the unwritten part of the first segment to write into the iovec.
650     iov[0].iov_base = const_cast<char*>(iter.Data());
651     iov[0].iov_len = iter.RemainingInSegment();
652     amt_to_write += iov[0].iov_len;
653     iter.Advance(msg->Buffers(), iov[0].iov_len);
654     iov_count++;
655 
656     // Store remaining segments to write into iovec.
657     //
658     // Don't add more than kMaxIOVecSize iovecs so that we avoid
659     // OS-dependent limits.  Also, stop adding iovecs if we've already
660     // prepared to write at least the full buffer size.
661     while (!iter.Done() && iov_count < kMaxIOVecSize &&
662            PipeBufHasSpaceAfter(amt_to_write)) {
663       char* data = iter.Data();
664       size_t size = iter.RemainingInSegment();
665 
666       iov[iov_count].iov_base = data;
667       iov[iov_count].iov_len = size;
668       iov_count++;
669       amt_to_write += size;
670       iter.Advance(msg->Buffers(), size);
671     }
672 
673     const bool intentional_short_write = !iter.Done();
674     msgh.msg_iov = iov;
675     msgh.msg_iovlen = iov_count;
676 
677     ssize_t bytes_written =
678         HANDLE_EINTR(corrected_sendmsg(pipe_, &msgh, MSG_DONTWAIT));
679 
680 #if !defined(OS_MACOSX)
681     // On OSX CommitAll gets called later, once we get the
682     // RECEIVED_FDS_MESSAGE_TYPE message.
683     if (bytes_written > 0) msg->file_descriptor_set()->CommitAll();
684 #endif
685 
686     if (bytes_written < 0) {
687       switch (errno) {
688         case EAGAIN:
689           // Not an error; the sendmsg would have blocked, so return to the
690           // event loop and try again later.
691           break;
692 #if defined(OS_MACOSX) || defined(OS_NETBSD)
693           // (Note: this comment is copied from https://crrev.com/86c3d9ef4fdf6;
694           // see also bug 1142693 comment #73.)
695           //
696           // On OS X if sendmsg() is trying to send fds between processes and
697           // there isn't enough room in the output buffer to send the fd
698           // structure over atomically then EMSGSIZE is returned. The same
699           // applies to NetBSD as well.
700           //
701           // EMSGSIZE presents a problem since the system APIs can only call us
702           // when there's room in the socket buffer and not when there is
703           // "enough" room.
704           //
705           // The current behavior is to return to the event loop when EMSGSIZE
706           // is received and hopefull service another FD.  This is however still
707           // technically a busy wait since the event loop will call us right
708           // back until the receiver has read enough data to allow passing the
709           // FD over atomically.
710         case EMSGSIZE:
711           // Because this is likely to result in a busy-wait, we'll try to make
712           // it easier for the receiver to make progress.
713           sched_yield();
714           break;
715 #endif
716         default:
717           if (!ErrorIsBrokenPipe(errno)) {
718             CHROMIUM_LOG(ERROR) << "pipe error: " << strerror(errno);
719           }
720           return false;
721       }
722     }
723 
724     if (intentional_short_write ||
725         static_cast<size_t>(bytes_written) != amt_to_write) {
726       // If write() fails with EAGAIN then bytes_written will be -1.
727       if (bytes_written > 0) {
728         MOZ_DIAGNOSTIC_ASSERT(intentional_short_write ||
729                               static_cast<size_t>(bytes_written) <
730                                   amt_to_write);
731         partial_write_iter_.ref().AdvanceAcrossSegments(msg->Buffers(),
732                                                         bytes_written);
733         // We should not hit the end of the buffer.
734         MOZ_DIAGNOSTIC_ASSERT(!partial_write_iter_.ref().Done());
735       }
736 
737       // Tell libevent to call us back once things are unblocked.
738       is_blocked_on_write_ = true;
739       MessageLoopForIO::current()->WatchFileDescriptor(
740           pipe_,
741           false,  // One shot
742           MessageLoopForIO::WATCH_WRITE, &write_watcher_, this);
743       return true;
744     } else {
745       partial_write_iter_.reset();
746 
747 #if defined(OS_MACOSX)
748       if (!msg->file_descriptor_set()->empty())
749         pending_fds_.push_back(
750             PendingDescriptors(msg->fd_cookie(), msg->file_descriptor_set()));
751 #endif
752 
753       // Message sent OK!
754 
755       AddIPCProfilerMarker(*msg, other_pid_, MessageDirection::eSending,
756                            MessagePhase::TransferEnd);
757 
758 #ifdef IPC_MESSAGE_DEBUG_EXTRA
759       DLOG(INFO) << "sent message @" << msg << " on channel @" << this
760                  << " with type " << msg->type();
761 #endif
762       OutputQueuePop();
763       // msg has been destroyed, so clear the dangling reference.
764       msg = nullptr;
765     }
766   }
767   return true;
768 }
769 
Send(mozilla::UniquePtr<Message> message)770 bool Channel::ChannelImpl::Send(mozilla::UniquePtr<Message> message) {
771 #ifdef IPC_MESSAGE_DEBUG_EXTRA
772   DLOG(INFO) << "sending message @" << message.get() << " on channel @" << this
773              << " with type " << message->type() << " ("
774              << output_queue_.Count() << " in queue)";
775 #endif
776 
777 #ifdef FUZZING
778   message = mozilla::ipc::Faulty::instance().MutateIPCMessage(
779       "Channel::ChannelImpl::Send", std::move(message));
780 #endif
781 
782   // If the channel has been closed, ProcessOutgoingMessages() is never going
783   // to pop anything off output_queue; output_queue will only get emptied when
784   // the channel is destructed.  We might as well delete message now, instead
785   // of waiting for the channel to be destructed.
786   if (closed_) {
787     if (mozilla::ipc::LoggingEnabled()) {
788       fprintf(stderr,
789               "Can't send message %s, because this channel is closed.\n",
790               message->name());
791     }
792     return false;
793   }
794 
795   OutputQueuePush(std::move(message));
796   if (!waiting_connect_) {
797     if (!is_blocked_on_write_) {
798       if (!ProcessOutgoingMessages()) return false;
799     }
800   }
801 
802   return true;
803 }
804 
GetClientFileDescriptorMapping(int * src_fd,int * dest_fd) const805 void Channel::ChannelImpl::GetClientFileDescriptorMapping(int* src_fd,
806                                                           int* dest_fd) const {
807   DCHECK(mode_ == MODE_SERVER);
808   *src_fd = client_pipe_;
809   *dest_fd = gClientChannelFd;
810 }
811 
CloseClientFileDescriptor()812 void Channel::ChannelImpl::CloseClientFileDescriptor() {
813   if (client_pipe_ != -1) {
814     IGNORE_EINTR(close(client_pipe_));
815     client_pipe_ = -1;
816   }
817 }
818 
819 // Called by libevent when we can read from th pipe without blocking.
OnFileCanReadWithoutBlocking(int fd)820 void Channel::ChannelImpl::OnFileCanReadWithoutBlocking(int fd) {
821   if (!waiting_connect_ && fd == pipe_) {
822     if (!ProcessIncomingMessages()) {
823       Close();
824       listener_->OnChannelError();
825       // The OnChannelError() call may delete this, so we need to exit now.
826       return;
827     }
828   }
829 }
830 
831 #if defined(OS_MACOSX)
CloseDescriptors(uint32_t pending_fd_id)832 void Channel::ChannelImpl::CloseDescriptors(uint32_t pending_fd_id) {
833   DCHECK(pending_fd_id != 0);
834   for (std::list<PendingDescriptors>::iterator i = pending_fds_.begin();
835        i != pending_fds_.end(); i++) {
836     if ((*i).id == pending_fd_id) {
837       (*i).fds->CommitAll();
838       pending_fds_.erase(i);
839       return;
840     }
841   }
842   DCHECK(false) << "pending_fd_id not in our list!";
843 }
844 #endif
845 
OutputQueuePush(mozilla::UniquePtr<Message> msg)846 void Channel::ChannelImpl::OutputQueuePush(mozilla::UniquePtr<Message> msg) {
847   mozilla::LogIPCMessage::LogDispatchWithPid(msg.get(), other_pid_);
848 
849   MOZ_DIAGNOSTIC_ASSERT(!closed_);
850   msg->AssertAsLargeAsHeader();
851   output_queue_.Push(std::move(msg));
852   output_queue_length_++;
853 }
854 
OutputQueuePop()855 void Channel::ChannelImpl::OutputQueuePop() {
856   // Clear any reference to the front of output_queue_ before we destroy it.
857   partial_write_iter_.reset();
858 
859   mozilla::UniquePtr<Message> message = output_queue_.Pop();
860   output_queue_length_--;
861 }
862 
863 // Called by libevent when we can write to the pipe without blocking.
OnFileCanWriteWithoutBlocking(int fd)864 void Channel::ChannelImpl::OnFileCanWriteWithoutBlocking(int fd) {
865   if (!ProcessOutgoingMessages()) {
866     Close();
867     listener_->OnChannelError();
868   }
869 }
870 
Close()871 void Channel::ChannelImpl::Close() {
872   // Close can be called multiple times, so we need to make sure we're
873   // idempotent.
874 
875   // Unregister libevent for the listening socket and close it.
876   server_listen_connection_watcher_.StopWatchingFileDescriptor();
877 
878   if (server_listen_pipe_ != -1) {
879     IGNORE_EINTR(close(server_listen_pipe_));
880     server_listen_pipe_ = -1;
881   }
882 
883   // Unregister libevent for the FIFO and close it.
884   read_watcher_.StopWatchingFileDescriptor();
885   write_watcher_.StopWatchingFileDescriptor();
886   if (pipe_ != -1) {
887     IGNORE_EINTR(close(pipe_));
888     SetPipe(-1);
889   }
890   if (client_pipe_ != -1) {
891     IGNORE_EINTR(close(client_pipe_));
892     client_pipe_ = -1;
893   }
894 
895   while (!output_queue_.IsEmpty()) {
896     OutputQueuePop();
897   }
898 
899   // Close any outstanding, received file descriptors
900   for (std::vector<int>::iterator i = input_overflow_fds_.begin();
901        i != input_overflow_fds_.end(); ++i) {
902     IGNORE_EINTR(close(*i));
903   }
904   input_overflow_fds_.clear();
905 
906 #if defined(OS_MACOSX)
907   for (std::list<PendingDescriptors>::iterator i = pending_fds_.begin();
908        i != pending_fds_.end(); i++) {
909     (*i).fds->CommitAll();
910   }
911   pending_fds_.clear();
912 #endif
913 
914   closed_ = true;
915 }
916 
Unsound_IsClosed() const917 bool Channel::ChannelImpl::Unsound_IsClosed() const { return closed_; }
918 
Unsound_NumQueuedMessages() const919 uint32_t Channel::ChannelImpl::Unsound_NumQueuedMessages() const {
920   return output_queue_length_;
921 }
922 
923 //------------------------------------------------------------------------------
924 // Channel's methods simply call through to ChannelImpl.
Channel(const ChannelId & channel_id,Mode mode,Listener * listener)925 Channel::Channel(const ChannelId& channel_id, Mode mode, Listener* listener)
926     : channel_impl_(new ChannelImpl(channel_id, mode, listener)) {
927   MOZ_COUNT_CTOR(IPC::Channel);
928 }
929 
Channel(int fd,Mode mode,Listener * listener)930 Channel::Channel(int fd, Mode mode, Listener* listener)
931     : channel_impl_(new ChannelImpl(fd, mode, listener)) {
932   MOZ_COUNT_CTOR(IPC::Channel);
933 }
934 
~Channel()935 Channel::~Channel() {
936   MOZ_COUNT_DTOR(IPC::Channel);
937   delete channel_impl_;
938 }
939 
Connect()940 bool Channel::Connect() { return channel_impl_->Connect(); }
941 
Close()942 void Channel::Close() { channel_impl_->Close(); }
943 
set_listener(Listener * listener)944 Channel::Listener* Channel::set_listener(Listener* listener) {
945   return channel_impl_->set_listener(listener);
946 }
947 
Send(mozilla::UniquePtr<Message> message)948 bool Channel::Send(mozilla::UniquePtr<Message> message) {
949   return channel_impl_->Send(std::move(message));
950 }
951 
GetClientFileDescriptorMapping(int * src_fd,int * dest_fd) const952 void Channel::GetClientFileDescriptorMapping(int* src_fd, int* dest_fd) const {
953   return channel_impl_->GetClientFileDescriptorMapping(src_fd, dest_fd);
954 }
955 
ResetFileDescriptor(int fd)956 void Channel::ResetFileDescriptor(int fd) {
957   channel_impl_->ResetFileDescriptor(fd);
958 }
959 
GetFileDescriptor() const960 int Channel::GetFileDescriptor() const {
961   return channel_impl_->GetFileDescriptor();
962 }
963 
CloseClientFileDescriptor()964 void Channel::CloseClientFileDescriptor() {
965   channel_impl_->CloseClientFileDescriptor();
966 }
967 
OtherPid() const968 int32_t Channel::OtherPid() const { return channel_impl_->OtherPid(); }
969 
Unsound_IsClosed() const970 bool Channel::Unsound_IsClosed() const {
971   return channel_impl_->Unsound_IsClosed();
972 }
973 
Unsound_NumQueuedMessages() const974 uint32_t Channel::Unsound_NumQueuedMessages() const {
975   return channel_impl_->Unsound_NumQueuedMessages();
976 }
977 
978 // static
GenerateVerifiedChannelID()979 Channel::ChannelId Channel::GenerateVerifiedChannelID() { return {}; }
980 
981 // static
ChannelIDForCurrentProcess()982 Channel::ChannelId Channel::ChannelIDForCurrentProcess() { return {}; }
983 
984 }  // namespace IPC
985