// Copyright 2014 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 "sandbox/mac/launchd_interception_server.h"

#include <servers/bootstrap.h>

#include "base/logging.h"
#include "base/mac/mac_util.h"
#include "base/mac/mach_logging.h"
#include "sandbox/mac/bootstrap_sandbox.h"
#include "sandbox/mac/mach_message_server.h"
#include "sandbox/mac/os_compatibility.h"
#include "sandbox/mac/xpc_message_server.h"

namespace sandbox {

// The buffer size for all launchd messages. This comes from
// sizeof(union __RequestUnion__vproc_mig_job_subsystem) in launchd, and it
// is larger than the __ReplyUnion.
const mach_msg_size_t kBufferSize = 2096;

LaunchdInterceptionServer::LaunchdInterceptionServer(
    const BootstrapSandbox* sandbox)
    : sandbox_(sandbox),
      xpc_launchd_(false),
      sandbox_port_(MACH_PORT_NULL),
      compat_shim_(OSCompatibility::CreateForPlatform()) {
}

LaunchdInterceptionServer::~LaunchdInterceptionServer() {
}

bool LaunchdInterceptionServer::Initialize(mach_port_t server_receive_right) {
  mach_port_t task = mach_task_self();
  kern_return_t kr;

  // Allocate the dummy sandbox port.
  mach_port_t port;
  if ((kr = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &port)) !=
          KERN_SUCCESS) {
    MACH_LOG(ERROR, kr) << "Failed to allocate dummy sandbox port.";
    return false;
  }
  sandbox_port_.reset(port);
  if ((kr = mach_port_insert_right(task, sandbox_port_.get(),
          sandbox_port_.get(), MACH_MSG_TYPE_MAKE_SEND) != KERN_SUCCESS)) {
    MACH_LOG(ERROR, kr) << "Failed to allocate dummy sandbox port send right.";
    return false;
  }
  sandbox_send_port_.reset(sandbox_port_.get());

  if (base::mac::IsOSYosemiteOrLater()) {
    message_server_.reset(new XPCMessageServer(this, server_receive_right));
    xpc_launchd_ = true;
  } else {
    message_server_.reset(
        new MachMessageServer(this, server_receive_right, kBufferSize));
  }
  return message_server_->Initialize();
}

void LaunchdInterceptionServer::DemuxMessage(IPCMessage request) {
  const uint64_t message_subsystem =
      compat_shim_->GetMessageSubsystem(request);
  const uint64_t message_id = compat_shim_->GetMessageID(request);
  VLOG(3) << "Incoming message #" << message_subsystem << "," << message_id;

  pid_t sender_pid = message_server_->GetMessageSenderPID(request);
  const BootstrapSandboxPolicy* policy =
      sandbox_->PolicyForProcess(sender_pid);
  if (policy == NULL) {
    // No sandbox policy is in place for the sender of this message, which
    // means it came from the unknown. Reject it.
    VLOG(3) << "Message from unknown pid " << sender_pid << " rejected.";
    message_server_->RejectMessage(request, MIG_REMOTE_ERROR);
    return;
  }

  if (compat_shim_->IsServiceLookUpRequest(request)) {
    // Filter messages sent via bootstrap_look_up to enforce the sandbox policy
    // over the bootstrap namespace.
    HandleLookUp(request, policy);
  } else if (compat_shim_->IsVprocSwapInteger(request)) {
    // Ensure that any vproc_swap_integer requests are safe.
    HandleSwapInteger(request);
  } else if (compat_shim_->IsXPCDomainManagement(request)) {
    // XPC domain management requests just require an ACK.
    message_server_->SendReply(message_server_->CreateReply(request));
  } else {
    // All other messages are not permitted.
    VLOG(1) << "Rejecting unhandled message #" << message_id;
    message_server_->RejectMessage(request, MIG_REMOTE_ERROR);
  }
}

void LaunchdInterceptionServer::HandleLookUp(
    IPCMessage request,
    const BootstrapSandboxPolicy* policy) {
  const std::string request_service_name(
      compat_shim_->GetServiceLookupName(request));
  VLOG(2) << "Incoming look_up2 request for " << request_service_name;

  // Find the Rule for this service. If a named rule is not found, use the
  // default specified by the policy.
  const BootstrapSandboxPolicy::NamedRules::const_iterator it =
      policy->rules.find(request_service_name);
  Rule rule(policy->default_rule);
  if (it != policy->rules.end())
    rule = it->second;

  if (rule.result == POLICY_ALLOW) {
    // This service is explicitly allowed, so this message will not be
    // intercepted by the sandbox.
    VLOG(1) << "Permitting and forwarding look_up2: " << request_service_name;
    ForwardMessage(request);
  } else if (rule.result == POLICY_DENY_ERROR) {
    // The child is not permitted to look up this service. Send a MIG error
    // reply to the client. Returning a NULL or unserviced port for a look up
    // can cause clients to crash or hang.
    VLOG(1) << "Denying look_up2 with MIG error: " << request_service_name;
    message_server_->RejectMessage(request, BOOTSTRAP_UNKNOWN_SERVICE);
  } else if (rule.result == POLICY_DENY_DUMMY_PORT ||
             rule.result == POLICY_SUBSTITUTE_PORT) {
    // The policy result is to deny access to the real service port, replying
    // with a sandboxed port in its stead. Use either the dummy sandbox_port_
    // or the one specified in the policy.
    VLOG(1) << "Intercepting look_up2 with a sandboxed service port: "
            << request_service_name;

    mach_port_t result_port;
    if (rule.result == POLICY_DENY_DUMMY_PORT)
      result_port = sandbox_port_.get();
    else
      result_port = rule.substitute_port;

    IPCMessage reply = message_server_->CreateReply(request);
    compat_shim_->WriteServiceLookUpReply(reply, result_port);
    // If the message was sent successfully, clear the result_port out of the
    // message so that it is not destroyed at the end of ReceiveMessage. The
    // above-inserted right has been moved out of the process, and destroying
    // the message will unref yet another right.
    if (message_server_->SendReply(reply))
      compat_shim_->WriteServiceLookUpReply(reply, MACH_PORT_NULL);
  } else {
    NOTREACHED();
  }
}

void LaunchdInterceptionServer::HandleSwapInteger(IPCMessage request) {
  // Only allow getting information out of launchd. Do not allow setting
  // values. Two commonly observed values that are retrieved are
  // VPROC_GSK_MGR_PID and VPROC_GSK_TRANSACTIONS_ENABLED.
  if (compat_shim_->IsSwapIntegerReadOnly(request)) {
    VLOG(2) << "Forwarding vproc swap_integer message.";
    ForwardMessage(request);
  } else {
    VLOG(2) << "Rejecting non-read-only swap_integer message.";
    message_server_->RejectMessage(request, BOOTSTRAP_NOT_PRIVILEGED);
  }
}
void LaunchdInterceptionServer::ForwardMessage(IPCMessage request) {
  // If launchd is using XPC, then when the request is forwarded, it must
  // contain a valid domain port. Because the client processes are sandboxed,
  // they have not had their launchd domains uncorked (and launchd will
  // reject the message as being from an invalid client). Instead, provide the
  // original bootstrap as the domain port, so launchd services the request
  // as if it were coming from the sandbox host process (this).
  if (xpc_launchd_) {
    // xpc_dictionary_set_mach_send increments the send right count.
    xpc_dictionary_set_mach_send(request.xpc, "domain-port",
                                 sandbox_->real_bootstrap_port());
  }

  message_server_->ForwardMessage(request, sandbox_->real_bootstrap_port());
}

}  // namespace sandbox
