// Copyright 2014 The Crashpad Authors
//
// 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 "test/mac/mach_multiprocess.h"

#include <Availability.h>
#include <bsm/libbsm.h>

#include <memory>
#include <string>
#include <tuple>

#include "base/auto_reset.h"
#include "base/mac/scoped_mach_port.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "test/mac/mach_errors.h"
#include "util/file/file_io.h"
#include "util/mach/bootstrap.h"
#include "util/mach/mach_extensions.h"
#include "util/mach/mach_message.h"
#include "util/misc/implicit_cast.h"
#include "util/misc/random_string.h"
#include "util/misc/scoped_forbid_return.h"

namespace {

// The “hello” message contains a send right to the child process’ task port.
struct SendHelloMessage : public mach_msg_base_t {
  mach_msg_port_descriptor_t port_descriptor;
};

struct ReceiveHelloMessage : public SendHelloMessage {
  union {
    mach_msg_trailer_t trailer;
    mach_msg_audit_trailer_t audit_trailer;
  };
};

}  // namespace

namespace crashpad {
namespace test {

namespace internal {

struct MachMultiprocessInfo {
  MachMultiprocessInfo()
      : service_name(),
        local_port(MACH_PORT_NULL),
        remote_port(MACH_PORT_NULL),
        child_task(TASK_NULL) {
  }

  std::string service_name;
  base::mac::ScopedMachReceiveRight local_port;
  base::mac::ScopedMachSendRight remote_port;
  base::mac::ScopedMachSendRight child_task;  // valid only in parent
};

}  // namespace internal

MachMultiprocess::MachMultiprocess() : Multiprocess(), info_(nullptr) {
}

void MachMultiprocess::Run() {
  ASSERT_EQ(info_, nullptr);
  std::unique_ptr<internal::MachMultiprocessInfo> info(
      new internal::MachMultiprocessInfo);
  base::AutoReset<internal::MachMultiprocessInfo*> reset_info(&info_,
                                                              info.get());

  return Multiprocess::Run();
}

MachMultiprocess::~MachMultiprocess() {
}

void MachMultiprocess::PreFork() {
  ASSERT_NO_FATAL_FAILURE(Multiprocess::PreFork());

  // Set up the parent port and register it with the bootstrap server before
  // forking, so that it’s guaranteed to be there when the child attempts to
  // look it up.
  info_->service_name = "org.chromium.crashpad.test.mach_multiprocess.";
  info_->service_name.append(RandomString());

  info_->local_port = BootstrapCheckIn(info_->service_name);
  ASSERT_TRUE(info_->local_port.is_valid());
}

mach_port_t MachMultiprocess::LocalPort() const {
  EXPECT_TRUE(info_->local_port.is_valid());
  return info_->local_port.get();
}

mach_port_t MachMultiprocess::RemotePort() const {
  EXPECT_TRUE(info_->remote_port.is_valid());
  return info_->remote_port.get();
}

task_t MachMultiprocess::ChildTask() const {
  EXPECT_TRUE(info_->child_task.is_valid());
  return info_->child_task.get();
}

void MachMultiprocess::MultiprocessParent() {
  ReceiveHelloMessage message = {};

  kern_return_t kr = mach_msg(&message.header,
                              MACH_RCV_MSG | kMachMessageReceiveAuditTrailer,
                              0,
                              sizeof(message),
                              info_->local_port.get(),
                              MACH_MSG_TIMEOUT_NONE,
                              MACH_PORT_NULL);
  ASSERT_EQ(kr, MACH_MSG_SUCCESS) << MachErrorMessage(kr, "mach_msg");

  // Comb through the entire message, checking every field against its expected
  // value.
  EXPECT_EQ(message.header.msgh_bits,
            MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND, MACH_MSG_TYPE_MOVE_SEND) |
                MACH_MSGH_BITS_COMPLEX);
  ASSERT_EQ(message.header.msgh_size, sizeof(SendHelloMessage));
  EXPECT_EQ(message.header.msgh_local_port, info_->local_port);
  ASSERT_EQ(message.body.msgh_descriptor_count, 1u);
  EXPECT_EQ(message.port_descriptor.disposition,
            implicit_cast<mach_msg_type_name_t>(MACH_MSG_TYPE_MOVE_SEND));
  ASSERT_EQ(
      message.port_descriptor.type,
      implicit_cast<mach_msg_descriptor_type_t>(MACH_MSG_PORT_DESCRIPTOR));
  ASSERT_EQ(message.audit_trailer.msgh_trailer_type,
            implicit_cast<mach_msg_trailer_type_t>(MACH_MSG_TRAILER_FORMAT_0));
  ASSERT_EQ(message.audit_trailer.msgh_trailer_size,
            sizeof(message.audit_trailer));
  EXPECT_EQ(message.audit_trailer.msgh_seqno, 0u);

  // Check the audit trailer’s values for sanity. This is a little bit of
  // overkill, but because the service was registered with the bootstrap server
  // and other processes will be able to look it up and send messages to it,
  // these checks disambiguate genuine failures later on in the test from those
  // that would occur if an errant process sends a message to this service.
#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8
  uid_t audit_auid;
  uid_t audit_euid;
  gid_t audit_egid;
  uid_t audit_ruid;
  gid_t audit_rgid;
  pid_t audit_pid;
  au_asid_t audit_asid;
  audit_token_to_au32(message.audit_trailer.msgh_audit,
                      &audit_auid,
                      &audit_euid,
                      &audit_egid,
                      &audit_ruid,
                      &audit_rgid,
                      &audit_pid,
                      &audit_asid,
                      nullptr);
#else
  uid_t audit_auid = audit_token_to_auid(message.audit_trailer.msgh_audit);
  uid_t audit_euid = audit_token_to_euid(message.audit_trailer.msgh_audit);
  gid_t audit_egid = audit_token_to_egid(message.audit_trailer.msgh_audit);
  uid_t audit_ruid = audit_token_to_ruid(message.audit_trailer.msgh_audit);
  gid_t audit_rgid = audit_token_to_rgid(message.audit_trailer.msgh_audit);
  pid_t audit_pid = audit_token_to_pid(message.audit_trailer.msgh_audit);
  au_asid_t audit_asid = audit_token_to_asid(message.audit_trailer.msgh_audit);
#endif
  EXPECT_EQ(audit_euid, geteuid());
  EXPECT_EQ(audit_egid, getegid());
  EXPECT_EQ(audit_ruid, getuid());
  EXPECT_EQ(audit_rgid, getgid());
  ASSERT_EQ(audit_pid, ChildPID());

  ASSERT_EQ(AuditPIDFromMachMessageTrailer(&message.trailer), ChildPID());

  auditinfo_addr_t audit_info;
  int rv = getaudit_addr(&audit_info, sizeof(audit_info));
  ASSERT_EQ(rv, 0) << ErrnoMessage("getaudit_addr");
  EXPECT_EQ(audit_auid, audit_info.ai_auid);
  EXPECT_EQ(audit_asid, audit_info.ai_asid);

  // Retrieve the remote port from the message header, and the child’s task port
  // from the message body.
  info_->remote_port.reset(message.header.msgh_remote_port);
  info_->child_task.reset(message.port_descriptor.name);

  // Verify that the child’s task port is what it purports to be.
  int mach_pid;
  kr = pid_for_task(info_->child_task.get(), &mach_pid);
  ASSERT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "pid_for_task");
  ASSERT_EQ(mach_pid, ChildPID());

  MachMultiprocessParent();

  info_->remote_port.reset();
  info_->local_port.reset();
}

void MachMultiprocess::MultiprocessChild() {
  ScopedForbidReturn forbid_return;

  // local_port is not valid in the forked child process.
  std::ignore = info_->local_port.release();

  info_->local_port.reset(NewMachPort(MACH_PORT_RIGHT_RECEIVE));
  ASSERT_NE(info_->local_port, kMachPortNull);

  // The remote port can be obtained from the bootstrap server.
  info_->remote_port = BootstrapLookUp(info_->service_name);
  ASSERT_NE(info_->remote_port, kMachPortNull);

  // The “hello” message will provide the parent with its remote port, a send
  // right to the child task’s local port receive right. It will also carry a
  // send right to the child task’s task port.
  SendHelloMessage message = {};
  message.header.msgh_bits =
      MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND) |
      MACH_MSGH_BITS_COMPLEX;
  message.header.msgh_size = sizeof(message);
  message.header.msgh_remote_port = info_->remote_port.get();
  message.header.msgh_local_port = info_->local_port.get();
  message.body.msgh_descriptor_count = 1;
  message.port_descriptor.name = mach_task_self();
  message.port_descriptor.disposition = MACH_MSG_TYPE_COPY_SEND;
  message.port_descriptor.type = MACH_MSG_PORT_DESCRIPTOR;

  kern_return_t kr = mach_msg(&message.header,
                              MACH_SEND_MSG,
                              message.header.msgh_size,
                              0,
                              MACH_PORT_NULL,
                              MACH_MSG_TIMEOUT_NONE,
                              MACH_PORT_NULL);
  ASSERT_EQ(kr, MACH_MSG_SUCCESS) << MachErrorMessage(kr, "mach_msg");

  MachMultiprocessChild();

  info_->remote_port.reset();
  info_->local_port.reset();

  // Close the write pipe now, for cases where the parent is waiting on it to
  // be closed as an indication that the child has finished.
  CloseWritePipe();

  // Wait for the parent process to close its end of the pipe. The child process
  // needs to remain alive until then because the parent process will attempt to
  // verify it using the task port it has access to via ChildTask().
  CheckedReadFileAtEOF(ReadPipeHandle());

  if (testing::Test::HasFailure()) {
    // Trigger the ScopedForbidReturn destructor.
    return;
  }

  forbid_return.Disarm();
}

}  // namespace test
}  // namespace crashpad
