// Copyright 2014 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "util/mach/child_port_handshake.h"

#include <errno.h>
#include <pthread.h>
#include <stdint.h>
#include <sys/event.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#include <algorithm>
#include <utility>

#include "base/check_op.h"
#include "base/cxx17_backports.h"
#include "base/logging.h"
#include "base/mac/mach_logging.h"
#include "base/mac/scoped_mach_port.h"
#include "base/notreached.h"
#include "base/posix/eintr_wrapper.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "util/file/file_io.h"
#include "util/mach/bootstrap.h"
#include "util/mach/child_port.h"
#include "util/mach/child_port_server.h"
#include "util/mach/mach_extensions.h"
#include "util/mach/mach_message.h"
#include "util/mach/mach_message_server.h"
#include "util/misc/implicit_cast.h"
#include "util/misc/random_string.h"

namespace crashpad {
namespace {

class ChildPortHandshakeServer final : public ChildPortServer::Interface {
 public:
  ChildPortHandshakeServer();

  ChildPortHandshakeServer(const ChildPortHandshakeServer&) = delete;
  ChildPortHandshakeServer& operator=(const ChildPortHandshakeServer&) = delete;

  ~ChildPortHandshakeServer();

  mach_port_t RunServer(base::ScopedFD server_write_fd,
                        ChildPortHandshake::PortRightType port_right_type);

 private:
  // ChildPortServer::Interface:
  kern_return_t HandleChildPortCheckIn(child_port_server_t server,
                                       child_port_token_t token,
                                       mach_port_t port,
                                       mach_msg_type_name_t right_type,
                                       const mach_msg_trailer_t* trailer,
                                       bool* destroy_request) override;

  child_port_token_t token_;
  mach_port_t port_;
  mach_msg_type_name_t right_type_;
  bool checked_in_;
};

ChildPortHandshakeServer::ChildPortHandshakeServer()
    : token_(0),
      port_(MACH_PORT_NULL),
      right_type_(MACH_MSG_TYPE_PORT_NONE),
      checked_in_(false) {
}

ChildPortHandshakeServer::~ChildPortHandshakeServer() {
}

mach_port_t ChildPortHandshakeServer::RunServer(
    base::ScopedFD server_write_fd,
    ChildPortHandshake::PortRightType port_right_type) {
  DCHECK_EQ(port_, kMachPortNull);
  DCHECK(!checked_in_);
  DCHECK(server_write_fd.is_valid());

  // Initialize the token and share it with the client via the pipe.
  token_ = base::RandUint64();
  if (!LoggingWriteFile(server_write_fd.get(), &token_, sizeof(token_))) {
    LOG(WARNING) << "no client check-in";
    return MACH_PORT_NULL;
  }

  // Create a unique name for the bootstrap service mapping. Make it unguessable
  // to prevent outsiders from grabbing the name first, which would cause
  // bootstrap_check_in() to fail.
  uint64_t thread_id;
  errno = pthread_threadid_np(pthread_self(), &thread_id);
  PCHECK(errno == 0) << "pthread_threadid_np";
  std::string service_name = base::StringPrintf(
      "org.chromium.crashpad.child_port_handshake.%d.%llu.%s",
      getpid(),
      thread_id,
      RandomString().c_str());

  // Check the new service in with the bootstrap server, obtaining a receive
  // right for it.
  base::mac::ScopedMachReceiveRight server_port(BootstrapCheckIn(service_name));
  CHECK(server_port.is_valid());

  // Share the service name with the client via the pipe.
  uint32_t service_name_length = service_name.size();
  if (!LoggingWriteFile(server_write_fd.get(),
                        &service_name_length,
                        sizeof(service_name_length))) {
    LOG(WARNING) << "no client check-in";
    return MACH_PORT_NULL;
  }

  if (!LoggingWriteFile(
          server_write_fd.get(), service_name.c_str(), service_name_length)) {
    LOG(WARNING) << "no client check-in";
    return MACH_PORT_NULL;
  }

  // Prior to macOS 10.12, a kqueue cannot monitor a raw Mach receive right with
  // EVFILT_MACHPORT. It requires a port set. Compare 10.11.6
  // xnu-3248.60.10/osfmk/ipc/ipc_pset.c filt_machportattach(), which requires
  // MACH_PORT_RIGHT_PORT_SET, to 10.12.0 xnu-3789.1.32/osfmk/ipc/ipc_pset.c
  // filt_machportattach(), which also handles MACH_PORT_TYPE_RECEIVE. Create a
  // new port set and add the receive right to it.
  base::mac::ScopedMachPortSet server_port_set(
      NewMachPort(MACH_PORT_RIGHT_PORT_SET));
  CHECK(server_port_set.is_valid());

  kern_return_t kr = mach_port_insert_member(
      mach_task_self(), server_port.get(), server_port_set.get());
  MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_port_insert_member";

  // Set up a kqueue to monitor both the server’s receive right and the write
  // side of the pipe. Messages from the client will be received via the receive
  // right, and the pipe will show EOF if the client closes its read side
  // prematurely.
  base::ScopedFD kq(kqueue());
  PCHECK(kq != -1) << "kqueue";

  struct kevent changelist[2];
  EV_SET(&changelist[0],
         server_port_set.get(),
         EVFILT_MACHPORT,
         EV_ADD | EV_CLEAR,
         0,
         0,
         nullptr);
  EV_SET(&changelist[1],
         server_write_fd.get(),
         EVFILT_WRITE,
         EV_ADD | EV_CLEAR,
         0,
         0,
         nullptr);
  int rv = HANDLE_EINTR(kevent(
      kq.get(), changelist, base::size(changelist), nullptr, 0, nullptr));
  PCHECK(rv != -1) << "kevent";

  ChildPortServer child_port_server(this);

  bool blocking = true;
  DCHECK(!checked_in_);
  while (!checked_in_) {
    DCHECK_EQ(port_, kMachPortNull);

    // Get a kevent from the kqueue. Block while waiting for an event unless the
    // write pipe has arrived at EOF, in which case the kevent() should be
    // nonblocking. Although the client sends its check-in message before
    // closing the read side of the pipe, this organization allows the events to
    // be delivered out of order and the check-in message will still be
    // processed.
    struct kevent event;
    constexpr timespec nonblocking_timeout = {};
    const timespec* timeout = blocking ? nullptr : &nonblocking_timeout;
    rv = HANDLE_EINTR(kevent(kq.get(), nullptr, 0, &event, 1, timeout));
    PCHECK(rv != -1) << "kevent";

    if (rv == 0) {
      // Non-blocking kevent() with no events to return.
      DCHECK(!blocking);
      LOG(WARNING) << "no client check-in";
      return MACH_PORT_NULL;
    }

    DCHECK_EQ(rv, 1);

    if (event.flags & EV_ERROR) {
      // kevent() may have put its error here.
      errno = event.data;
      PLOG(FATAL) << "kevent";
    }

    switch (event.filter) {
      case EVFILT_MACHPORT: {
        // There’s something to receive on the port set.
        DCHECK_EQ(event.ident, server_port_set.get());

        // Run the message server in an inner loop instead of using
        // MachMessageServer::kPersistent. This allows the loop to exit as soon
        // as child_port_ is set, even if other messages are queued. This needs
        // to drain all messages, because the use of edge triggering (EV_CLEAR)
        // means that if more than one message is in the queue when kevent()
        // returns, no more notifications will be generated.
        while (!checked_in_) {
          // If a proper message is received from child_port_check_in(),
          // this will call HandleChildPortCheckIn().
          mach_msg_return_t mr =
              MachMessageServer::Run(&child_port_server,
                                     server_port_set.get(),
                                     MACH_MSG_OPTION_NONE,
                                     MachMessageServer::kOneShot,
                                     MachMessageServer::kReceiveLargeIgnore,
                                     kMachMessageTimeoutNonblocking);
          if (mr == MACH_RCV_TIMED_OUT) {
            break;
          } else if (mr != MACH_MSG_SUCCESS) {
            MACH_LOG(ERROR, mr) << "MachMessageServer::Run";
            return MACH_PORT_NULL;
          }
        }
        break;
      }

      case EVFILT_WRITE:
        // The write pipe is ready to be written to, or it’s at EOF. The former
        // case is uninteresting, but a notification for this may be presented
        // because the write pipe will be ready to be written to, at the latest,
        // when the client reads its messages from the read side of the same
        // pipe. Ignore that case. Multiple notifications for that situation
        // will not be generated because edge triggering (EV_CLEAR) is used
        // above.
        DCHECK_EQ(implicit_cast<int>(event.ident), server_write_fd.get());
        if (event.flags & EV_EOF) {
          // There are no readers attached to the write pipe. The client has
          // closed its side of the pipe. There can be one last shot at
          // receiving messages, in case the check-in message is delivered
          // out of order, after the EOF notification.
          blocking = false;
        }
        break;

      default:
        NOTREACHED();
        break;
    }
  }

  if (port_ == MACH_PORT_NULL) {
    return MACH_PORT_NULL;
  }

  bool mismatch = false;
  switch (port_right_type) {
    case ChildPortHandshake::PortRightType::kReceiveRight:
      if (right_type_ != MACH_MSG_TYPE_PORT_RECEIVE) {
        LOG(ERROR) << "expected receive right, observed " << right_type_;
        mismatch = true;
      }
      break;
    case ChildPortHandshake::PortRightType::kSendRight:
      if (right_type_ != MACH_MSG_TYPE_PORT_SEND &&
          right_type_ != MACH_MSG_TYPE_PORT_SEND_ONCE) {
        LOG(ERROR) << "expected send or send-once right, observed "
                   << right_type_;
        mismatch = true;
      }
      break;
  }

  if (mismatch) {
    MachMessageDestroyReceivedPort(port_, right_type_);
    port_ = MACH_PORT_NULL;
    return MACH_PORT_NULL;
  }

  mach_port_t port = MACH_PORT_NULL;
  std::swap(port_, port);
  return port;
}

kern_return_t ChildPortHandshakeServer::HandleChildPortCheckIn(
    child_port_server_t server,
    const child_port_token_t token,
    mach_port_t port,
    mach_msg_type_name_t right_type,
    const mach_msg_trailer_t* trailer,
    bool* destroy_request) {
  DCHECK_EQ(port_, kMachPortNull);
  DCHECK(!checked_in_);

  if (token != token_) {
    // If the token’s not correct, someone’s attempting to spoof the legitimate
    // client.
    LOG(WARNING) << "ignoring incorrect token";
    *destroy_request = true;
  } else {
    checked_in_ = true;

    if (right_type != MACH_MSG_TYPE_PORT_RECEIVE &&
        right_type != MACH_MSG_TYPE_PORT_SEND &&
        right_type != MACH_MSG_TYPE_PORT_SEND_ONCE) {
      // The message needs to carry a receive, send, or send-once right.
      LOG(ERROR) << "invalid right type " << right_type;
      *destroy_request = true;
    } else {
      // Communicate the child port and right type back to the RunServer().
      // *destroy_request is left at false, because RunServer() needs the right
      // to remain intact. It gives ownership of the right to its caller.
      port_ = port;
      right_type_ = right_type;
    }
  }

  // This is a MIG simpleroutine, there is no reply message.
  return MIG_NO_REPLY;
}

}  // namespace

ChildPortHandshake::ChildPortHandshake()
    : client_read_fd_(),
      server_write_fd_() {
  // Use socketpair() instead of pipe(). There is no way to suppress SIGPIPE on
  // pipes in Mac OS X 10.6, because the F_SETNOSIGPIPE fcntl() command was not
  // introduced until 10.7.
  int pipe_fds[2];
  PCHECK(socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_fds) == 0)
      << "socketpair";

  client_read_fd_.reset(pipe_fds[0]);
  server_write_fd_.reset(pipe_fds[1]);

  // Simulate pipe() semantics by shutting down the “wrong” sides of the socket.
  PCHECK(shutdown(server_write_fd_.get(), SHUT_RD) == 0) << "shutdown SHUT_RD";
  PCHECK(shutdown(client_read_fd_.get(), SHUT_WR) == 0) << "shutdown SHUT_WR";

  // SIGPIPE is undesirable when writing to this pipe. Allow broken-pipe writes
  // to fail with EPIPE instead.
  constexpr int value = 1;
  PCHECK(setsockopt(server_write_fd_.get(),
                    SOL_SOCKET,
                    SO_NOSIGPIPE,
                    &value,
                    sizeof(value)) == 0) << "setsockopt";
}

ChildPortHandshake::~ChildPortHandshake() {
}

base::ScopedFD ChildPortHandshake::ClientReadFD() {
  DCHECK(client_read_fd_.is_valid());
  return std::move(client_read_fd_);
}

base::ScopedFD ChildPortHandshake::ServerWriteFD() {
  DCHECK(server_write_fd_.is_valid());
  return std::move(server_write_fd_);
}

mach_port_t ChildPortHandshake::RunServer(PortRightType port_right_type) {
  client_read_fd_.reset();
  return RunServerForFD(std::move(server_write_fd_), port_right_type);
}

bool ChildPortHandshake::RunClient(mach_port_t port,
                                   mach_msg_type_name_t right_type) {
  server_write_fd_.reset();
  return RunClientForFD(std::move(client_read_fd_), port, right_type);
}

// static
mach_port_t ChildPortHandshake::RunServerForFD(base::ScopedFD server_write_fd,
                                               PortRightType port_right_type) {
  ChildPortHandshakeServer server;
  return server.RunServer(std::move(server_write_fd), port_right_type);
}

// static
bool ChildPortHandshake::RunClientForFD(base::ScopedFD client_read_fd,
                                        mach_port_t port,
                                        mach_msg_type_name_t right_type) {
  DCHECK(client_read_fd.is_valid());

  // Read the token and the service name from the read side of the pipe.
  child_port_token_t token;
  std::string service_name;
  if (!RunClientInternal_ReadPipe(
          client_read_fd.get(), &token, &service_name)) {
    return false;
  }

  // Look up the server and check in with it by providing the token and port.
  return RunClientInternal_SendCheckIn(service_name, token, port, right_type);
}

// static
bool ChildPortHandshake::RunClientInternal_ReadPipe(int client_read_fd,
                                                    child_port_token_t* token,
                                                    std::string* service_name) {
  // Read the token from the pipe.
  if (!LoggingReadFileExactly(client_read_fd, token, sizeof(*token))) {
    return false;
  }

  // Read the service name from the pipe.
  uint32_t service_name_length;
  if (!LoggingReadFileExactly(
          client_read_fd, &service_name_length, sizeof(service_name_length))) {
    return false;
  }

  service_name->resize(service_name_length);
  if (!service_name->empty() &&
      !LoggingReadFileExactly(
          client_read_fd, &(*service_name)[0], service_name_length)) {
    return false;
  }

  return true;
}

// static
bool ChildPortHandshake::RunClientInternal_SendCheckIn(
    const std::string& service_name,
    child_port_token_t token,
    mach_port_t port,
    mach_msg_type_name_t right_type) {
  // Get a send right to the server by looking up the service with the bootstrap
  // server by name.
  base::mac::ScopedMachSendRight server_port(BootstrapLookUp(service_name));
  if (server_port == kMachPortNull) {
    return false;
  }

  // Check in with the server.
  kern_return_t kr = child_port_check_in(
      server_port.get(), token, port, right_type);
  if (kr != KERN_SUCCESS) {
    MACH_LOG(ERROR, kr) << "child_port_check_in";
    return false;
  }

  return true;
}

}  // namespace crashpad
