// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/mac/mach_port_broker.h"

#include <bsm/libbsm.h>
#include <servers/bootstrap.h>

#include "base/logging.h"
#include "base/mac/foundation_util.h"
#include "base/mac/mach_logging.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"

namespace base {

namespace {

// Mach message structure used in the child as a sending message.
struct MachPortBroker_ChildSendMsg {
  mach_msg_header_t header;
  mach_msg_body_t body;
  mach_msg_port_descriptor_t child_task_port;
};

// Complement to the ChildSendMsg, this is used in the parent for receiving
// a message. Contains a message trailer with audit information.
struct MachPortBroker_ParentRecvMsg : public MachPortBroker_ChildSendMsg {
  mach_msg_audit_trailer_t trailer;
};

}  // namespace

// static
bool MachPortBroker::ChildSendTaskPortToParent(const std::string& name) {
  // Look up the named MachPortBroker port that's been registered with the
  // bootstrap server.
  mach_port_t parent_port;
  kern_return_t kr = bootstrap_look_up(bootstrap_port,
      const_cast<char*>(GetMachPortName(name, true).c_str()), &parent_port);
  if (kr != KERN_SUCCESS) {
    BOOTSTRAP_LOG(ERROR, kr) << "bootstrap_look_up";
    return false;
  }
  base::mac::ScopedMachSendRight scoped_right(parent_port);

  // Create the check in message. This will copy a send right on this process'
  // (the child's) task port and send it to the parent.
  MachPortBroker_ChildSendMsg msg;
  bzero(&msg, sizeof(msg));
  msg.header.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND) |
                         MACH_MSGH_BITS_COMPLEX;
  msg.header.msgh_remote_port = parent_port;
  msg.header.msgh_size = sizeof(msg);
  msg.body.msgh_descriptor_count = 1;
  msg.child_task_port.name = mach_task_self();
  msg.child_task_port.disposition = MACH_MSG_TYPE_PORT_SEND;
  msg.child_task_port.type = MACH_MSG_PORT_DESCRIPTOR;

  kr = mach_msg(&msg.header, MACH_SEND_MSG | MACH_SEND_TIMEOUT, sizeof(msg),
      0, MACH_PORT_NULL, 100 /*milliseconds*/, MACH_PORT_NULL);
  if (kr != KERN_SUCCESS) {
    MACH_LOG(ERROR, kr) << "mach_msg";
    return false;
  }

  return true;
}

// static
std::string MachPortBroker::GetMachPortName(const std::string& name,
                                            bool is_child) {
  // In child processes, use the parent's pid.
  const pid_t pid = is_child ? getppid() : getpid();
  return base::StringPrintf(
      "%s.%s.%d", base::mac::BaseBundleID(), name.c_str(), pid);
}

mach_port_t MachPortBroker::TaskForPid(base::ProcessHandle pid) const {
  base::AutoLock lock(lock_);
  MachPortBroker::MachMap::const_iterator it = mach_map_.find(pid);
  if (it == mach_map_.end())
    return MACH_PORT_NULL;
  return it->second;
}

MachPortBroker::MachPortBroker(const std::string& name) : name_(name) {}

MachPortBroker::~MachPortBroker() {}

bool MachPortBroker::Init() {
  DCHECK(server_port_.get() == MACH_PORT_NULL);

  // Check in with launchd and publish the service name.
  mach_port_t port;
  kern_return_t kr = bootstrap_check_in(
      bootstrap_port, GetMachPortName(name_, false).c_str(), &port);
  if (kr != KERN_SUCCESS) {
    BOOTSTRAP_LOG(ERROR, kr) << "bootstrap_check_in";
    return false;
  }
  server_port_.reset(port);

  // Start the dispatch source.
  std::string queue_name =
      base::StringPrintf("%s.MachPortBroker", base::mac::BaseBundleID());
  dispatch_source_.reset(new base::DispatchSourceMach(
      queue_name.c_str(), server_port_.get(), ^{ HandleRequest(); }));
  dispatch_source_->Resume();

  return true;
}

void MachPortBroker::AddPlaceholderForPid(base::ProcessHandle pid) {
  lock_.AssertAcquired();
  DCHECK_EQ(0u, mach_map_.count(pid));
  mach_map_[pid] = MACH_PORT_NULL;
}

void MachPortBroker::InvalidatePid(base::ProcessHandle pid) {
  lock_.AssertAcquired();

  MachMap::iterator mach_it = mach_map_.find(pid);
  if (mach_it != mach_map_.end()) {
    kern_return_t kr = mach_port_deallocate(mach_task_self(), mach_it->second);
    MACH_LOG_IF(WARNING, kr != KERN_SUCCESS, kr) << "mach_port_deallocate";
    mach_map_.erase(mach_it);
  }
}

void MachPortBroker::HandleRequest() {
  MachPortBroker_ParentRecvMsg msg;
  bzero(&msg, sizeof(msg));
  msg.header.msgh_size = sizeof(msg);
  msg.header.msgh_local_port = server_port_.get();

  const mach_msg_option_t options = MACH_RCV_MSG |
      MACH_RCV_TRAILER_TYPE(MACH_RCV_TRAILER_AUDIT) |
      MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT);

  kern_return_t kr = mach_msg(&msg.header,
                              options,
                              0,
                              sizeof(msg),
                              server_port_.get(),
                              MACH_MSG_TIMEOUT_NONE,
                              MACH_PORT_NULL);
  if (kr != KERN_SUCCESS) {
    MACH_LOG(ERROR, kr) << "mach_msg";
    return;
  }

  // Use the kernel audit information to make sure this message is from
  // a task that this process spawned. The kernel audit token contains the
  // unspoofable pid of the task that sent the message.
  //
  // TODO(rsesek): In the 10.7 SDK, there's audit_token_to_pid().
  pid_t child_pid;
  audit_token_to_au32(msg.trailer.msgh_audit,
      NULL, NULL, NULL, NULL, NULL, &child_pid, NULL, NULL);

  mach_port_t child_task_port = msg.child_task_port.name;

  // Take the lock and update the broker information.
  {
    base::AutoLock lock(lock_);
    FinalizePid(child_pid, child_task_port);
  }
  NotifyObservers(child_pid);
}

void MachPortBroker::FinalizePid(base::ProcessHandle pid,
                                 mach_port_t task_port) {
  lock_.AssertAcquired();

  MachMap::iterator it = mach_map_.find(pid);
  if (it == mach_map_.end()) {
    // Do nothing for unknown pids.
    LOG(ERROR) << "Unknown process " << pid << " is sending Mach IPC messages!";
    return;
  }

  DCHECK(it->second == MACH_PORT_NULL);
  if (it->second == MACH_PORT_NULL)
    it->second = task_port;
}

}  // namespace base
