// 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/bootstrap_sandbox.h"

#include <CoreFoundation/CoreFoundation.h>
#import <Foundation/Foundation.h>
#include <mach/mach.h>
#include <servers/bootstrap.h>

#include "base/logging.h"
#include "base/mac/mac_util.h"
#include "base/mac/mach_logging.h"
#include "base/mac/scoped_mach_port.h"
#include "base/mac/scoped_nsobject.h"
#include "base/process/kill.h"
#include "base/strings/stringprintf.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_timeouts.h"
#include "sandbox/mac/pre_exec_delegate.h"
#include "sandbox/mac/xpc.h"
#import "testing/gtest_mac.h"
#include "testing/multiprocess_func_list.h"

NSString* const kTestNotification = @"org.chromium.bootstrap_sandbox_test";

@interface DistributedNotificationObserver : NSObject {
 @private
  int receivedCount_;
  base::scoped_nsobject<NSString> object_;
}
- (int)receivedCount;
- (NSString*)object;
- (void)waitForNotification;
@end

@implementation DistributedNotificationObserver
- (id)init {
  if ((self = [super init])) {
    [[NSDistributedNotificationCenter defaultCenter]
        addObserver:self
           selector:@selector(observeNotification:)
               name:kTestNotification
             object:nil];
  }
  return self;
}

- (void)dealloc {
  [[NSDistributedNotificationCenter defaultCenter]
      removeObserver:self
                name:kTestNotification
              object:nil];
  [super dealloc];
}

- (int)receivedCount {
  return receivedCount_;
}

- (NSString*)object {
  return object_.get();
}

- (void)waitForNotification {
  object_.reset();
  CFRunLoopRunInMode(kCFRunLoopDefaultMode,
      TestTimeouts::action_timeout().InSeconds(), false);
}

- (void)observeNotification:(NSNotification*)notification {
  ++receivedCount_;
  object_.reset([[notification object] copy]);
  CFRunLoopStop(CFRunLoopGetCurrent());
}
@end

////////////////////////////////////////////////////////////////////////////////

namespace sandbox {

class BootstrapSandboxTest : public base::MultiProcessTest {
 public:
  void SetUp() override {
    base::MultiProcessTest::SetUp();

    sandbox_ = BootstrapSandbox::Create();
    ASSERT_TRUE(sandbox_.get());
  }

  BootstrapSandboxPolicy BaselinePolicy() {
    BootstrapSandboxPolicy policy;
    policy.rules["com.apple.cfprefsd.daemon"] = Rule(POLICY_ALLOW);
    return policy;
  }

  void RunChildWithPolicy(int policy_id,
                          const char* child_name,
                          base::ProcessHandle* out_pid) {
    std::unique_ptr<PreExecDelegate> pre_exec_delegate(
        sandbox_->NewClient(policy_id));

    base::LaunchOptions options;
    options.pre_exec_delegate = pre_exec_delegate.get();

    base::Process process = SpawnChildWithOptions(child_name, options);
    ASSERT_TRUE(process.IsValid());
    int code = 0;
    EXPECT_TRUE(process.WaitForExit(&code));
    EXPECT_EQ(0, code);
    if (out_pid)
      *out_pid = process.Pid();
  }

 protected:
  std::unique_ptr<BootstrapSandbox> sandbox_;
};

const char kNotificationTestMain[] = "PostNotification";

// Run the test without the sandbox.
TEST_F(BootstrapSandboxTest, DistributedNotifications_Unsandboxed) {
  base::scoped_nsobject<DistributedNotificationObserver> observer(
      [[DistributedNotificationObserver alloc] init]);

  base::Process process = SpawnChild(kNotificationTestMain);
  ASSERT_TRUE(process.IsValid());
  int code = 0;
  EXPECT_TRUE(process.WaitForExit(&code));
  EXPECT_EQ(0, code);

  [observer waitForNotification];
  EXPECT_EQ(1, [observer receivedCount]);
  EXPECT_EQ(process.Pid(), [[observer object] intValue]);
}

// Run the test with the sandbox enabled without notifications on the policy
// whitelist.
TEST_F(BootstrapSandboxTest, DistributedNotifications_SandboxDeny) {
  if (base::mac::IsAtLeastOS10_12()) {
    LOG(ERROR) << "BootstrapSandbox does not work on macOS Sierra or later.";
    return;
  }

  base::scoped_nsobject<DistributedNotificationObserver> observer(
      [[DistributedNotificationObserver alloc] init]);

  sandbox_->RegisterSandboxPolicy(1, BaselinePolicy());
  RunChildWithPolicy(1, kNotificationTestMain, NULL);

  [observer waitForNotification];
  EXPECT_EQ(0, [observer receivedCount]);
  EXPECT_EQ(nil, [observer object]);
}

// Run the test with notifications permitted.
TEST_F(BootstrapSandboxTest, DistributedNotifications_SandboxAllow) {
  if (base::mac::IsAtLeastOS10_12()) {
    LOG(ERROR) << "BootstrapSandbox does not work on macOS Sierra or later.";
    return;
  }

  base::scoped_nsobject<DistributedNotificationObserver> observer(
      [[DistributedNotificationObserver alloc] init]);

  BootstrapSandboxPolicy policy(BaselinePolicy());
  // 10.9:
  policy.rules["com.apple.distributed_notifications@Uv3"] = Rule(POLICY_ALLOW);
  policy.rules["com.apple.distributed_notifications@1v3"] = Rule(POLICY_ALLOW);
  // 10.6:
  policy.rules["com.apple.system.notification_center"] = Rule(POLICY_ALLOW);
  policy.rules["com.apple.distributed_notifications.2"] = Rule(POLICY_ALLOW);
  sandbox_->RegisterSandboxPolicy(2, policy);

  base::ProcessHandle pid;
  RunChildWithPolicy(2, kNotificationTestMain, &pid);

  [observer waitForNotification];
  EXPECT_EQ(1, [observer receivedCount]);
  EXPECT_EQ(pid, [[observer object] intValue]);
}

MULTIPROCESS_TEST_MAIN(PostNotification) {
  [[NSDistributedNotificationCenter defaultCenter]
      postNotificationName:kTestNotification
                    object:[NSString stringWithFormat:@"%d", getpid()]];
  return 0;
}

const char kTestServer[] = "org.chromium.test_bootstrap_server";

TEST_F(BootstrapSandboxTest, PolicyDenyError) {
  if (base::mac::IsAtLeastOS10_12()) {
    LOG(ERROR) << "BootstrapSandbox does not work on macOS Sierra or later.";
    return;
  }
  BootstrapSandboxPolicy policy(BaselinePolicy());
  policy.rules[kTestServer] = Rule(POLICY_DENY_ERROR);
  sandbox_->RegisterSandboxPolicy(1, policy);

  RunChildWithPolicy(1, "PolicyDenyError", NULL);
}

MULTIPROCESS_TEST_MAIN(PolicyDenyError) {
  mach_port_t port = MACH_PORT_NULL;
  kern_return_t kr = bootstrap_look_up(bootstrap_port, kTestServer,
      &port);
  CHECK_EQ(BOOTSTRAP_UNKNOWN_SERVICE, kr);
  CHECK(port == MACH_PORT_NULL);

  kr = bootstrap_look_up(bootstrap_port, "org.chromium.some_other_server",
      &port);
  CHECK_EQ(BOOTSTRAP_UNKNOWN_SERVICE, kr);
  CHECK(port == MACH_PORT_NULL);

  return 0;
}

TEST_F(BootstrapSandboxTest, PolicyDenyDummyPort) {
  if (base::mac::IsAtLeastOS10_12()) {
    LOG(ERROR) << "BootstrapSandbox does not work on macOS Sierra or later.";
    return;
  }
  BootstrapSandboxPolicy policy(BaselinePolicy());
  policy.rules[kTestServer] = Rule(POLICY_DENY_DUMMY_PORT);
  sandbox_->RegisterSandboxPolicy(1, policy);

  RunChildWithPolicy(1, "PolicyDenyDummyPort", NULL);
}

MULTIPROCESS_TEST_MAIN(PolicyDenyDummyPort) {
  mach_port_t port = MACH_PORT_NULL;
  kern_return_t kr = bootstrap_look_up(bootstrap_port, kTestServer,
      &port);
  CHECK_EQ(KERN_SUCCESS, kr);
  CHECK(port != MACH_PORT_NULL);
  return 0;
}

struct SubstitutePortAckSend {
  mach_msg_header_t header;
  char buf[32];
};

struct SubstitutePortAckRecv : public SubstitutePortAckSend {
  mach_msg_trailer_t trailer;
};

const char kSubstituteAck[] = "Hello, this is doge!";

TEST_F(BootstrapSandboxTest, PolicySubstitutePort) {
  if (base::mac::IsAtLeastOS10_12()) {
    LOG(ERROR) << "BootstrapSandbox does not work on macOS Sierra or later.";
    return;
  }

  mach_port_t task = mach_task_self();

  mach_port_t port;
  ASSERT_EQ(KERN_SUCCESS, mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE,
      &port));
  base::mac::ScopedMachReceiveRight scoped_port(port);

  mach_port_urefs_t send_rights = 0;
  ASSERT_EQ(KERN_SUCCESS, mach_port_get_refs(task, port, MACH_PORT_RIGHT_SEND,
      &send_rights));
  EXPECT_EQ(0u, send_rights);

  ASSERT_EQ(KERN_SUCCESS, mach_port_insert_right(task, port, port,
      MACH_MSG_TYPE_MAKE_SEND));
  base::mac::ScopedMachSendRight scoped_port_send(port);

  send_rights = 0;
  ASSERT_EQ(KERN_SUCCESS, mach_port_get_refs(task, port, MACH_PORT_RIGHT_SEND,
      &send_rights));
  EXPECT_EQ(1u, send_rights);

  BootstrapSandboxPolicy policy(BaselinePolicy());
  policy.rules[kTestServer] = Rule(port);
  sandbox_->RegisterSandboxPolicy(1, policy);

  RunChildWithPolicy(1, "PolicySubstitutePort", NULL);

  struct SubstitutePortAckRecv msg;
  bzero(&msg, sizeof(msg));
  msg.header.msgh_size = sizeof(msg);
  msg.header.msgh_local_port = port;
  kern_return_t kr = mach_msg(&msg.header, MACH_RCV_MSG, 0,
      msg.header.msgh_size, port,
      TestTimeouts::tiny_timeout().InMilliseconds(), MACH_PORT_NULL);
  EXPECT_EQ(KERN_SUCCESS, kr);

  send_rights = 0;
  ASSERT_EQ(KERN_SUCCESS, mach_port_get_refs(task, port, MACH_PORT_RIGHT_SEND,
      &send_rights));
  EXPECT_EQ(1u, send_rights);

  EXPECT_EQ(0, strncmp(kSubstituteAck, msg.buf, sizeof(msg.buf)));
}

MULTIPROCESS_TEST_MAIN(PolicySubstitutePort) {
  mach_port_t port = MACH_PORT_NULL;
  kern_return_t kr = bootstrap_look_up(bootstrap_port, kTestServer, &port);
  CHECK_EQ(KERN_SUCCESS, kr);
  CHECK(port != MACH_PORT_NULL);

  struct SubstitutePortAckSend msg;
  bzero(&msg, sizeof(msg));
  msg.header.msgh_size = sizeof(msg);
  msg.header.msgh_remote_port = port;
  msg.header.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MOVE_SEND);
  strncpy(msg.buf, kSubstituteAck, sizeof(msg.buf));

  CHECK_EQ(KERN_SUCCESS, mach_msg_send(&msg.header));

  return 0;
}

TEST_F(BootstrapSandboxTest, ForwardMessageInProcess) {
  mach_port_t task = mach_task_self();

  mach_port_t port;
  ASSERT_EQ(KERN_SUCCESS, mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE,
      &port));
  base::mac::ScopedMachReceiveRight scoped_port_recv(port);

  mach_port_urefs_t send_rights = 0;
  ASSERT_EQ(KERN_SUCCESS, mach_port_get_refs(task, port, MACH_PORT_RIGHT_SEND,
      &send_rights));
  EXPECT_EQ(0u, send_rights);

  ASSERT_EQ(KERN_SUCCESS, mach_port_insert_right(task, port, port,
      MACH_MSG_TYPE_MAKE_SEND));
  base::mac::ScopedMachSendRight scoped_port_send(port);

  send_rights = 0;
  ASSERT_EQ(KERN_SUCCESS, mach_port_get_refs(task, port, MACH_PORT_RIGHT_SEND,
      &send_rights));
  EXPECT_EQ(1u, send_rights);

  mach_port_t bp;
  ASSERT_EQ(KERN_SUCCESS, task_get_bootstrap_port(task, &bp));
  base::mac::ScopedMachSendRight scoped_bp(bp);

  char service_name[] = "org.chromium.sandbox.test.ForwardMessageInProcess";
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  kern_return_t kr = bootstrap_register(bp, service_name, port);
#pragma GCC diagnostic pop
  EXPECT_EQ(KERN_SUCCESS, kr);

  send_rights = 0;
  ASSERT_EQ(KERN_SUCCESS, mach_port_get_refs(task, port, MACH_PORT_RIGHT_SEND,
      &send_rights));
  EXPECT_EQ(1u, send_rights);

  mach_port_t service_port;
  EXPECT_EQ(KERN_SUCCESS, bootstrap_look_up(bp, service_name, &service_port));
  base::mac::ScopedMachSendRight scoped_service_port(service_port);

  send_rights = 0;
  ASSERT_EQ(KERN_SUCCESS, mach_port_get_refs(task, port, MACH_PORT_RIGHT_SEND,
      &send_rights));
  EXPECT_EQ(2u, send_rights);
}

const char kDefaultRuleTestAllow[] =
    "org.chromium.sandbox.test.DefaultRuleAllow";
const char kDefaultRuleTestDeny[] =
    "org.chromium.sandbox.test.DefaultRuleAllow.Deny";

TEST_F(BootstrapSandboxTest, DefaultRuleAllow) {
  if (base::mac::IsAtLeastOS10_12()) {
    LOG(ERROR) << "BootstrapSandbox does not work on macOS Sierra or later.";
    return;
  }

  mach_port_t task = mach_task_self();

  mach_port_t port;
  ASSERT_EQ(KERN_SUCCESS, mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE,
      &port));
  base::mac::ScopedMachReceiveRight scoped_port_recv(port);

  ASSERT_EQ(KERN_SUCCESS, mach_port_insert_right(task, port, port,
      MACH_MSG_TYPE_MAKE_SEND));
  base::mac::ScopedMachSendRight scoped_port_send(port);

  BootstrapSandboxPolicy policy;
  policy.default_rule = Rule(POLICY_ALLOW);
  policy.rules[kDefaultRuleTestAllow] = Rule(port);
  policy.rules[kDefaultRuleTestDeny] = Rule(POLICY_DENY_ERROR);
  sandbox_->RegisterSandboxPolicy(3, policy);

  base::scoped_nsobject<DistributedNotificationObserver> observer(
      [[DistributedNotificationObserver alloc] init]);

  int pid = 0;
  RunChildWithPolicy(3, "DefaultRuleAllow", &pid);
  EXPECT_GT(pid, 0);

  [observer waitForNotification];
  EXPECT_EQ(1, [observer receivedCount]);
  EXPECT_EQ(pid, [[observer object] intValue]);

  struct SubstitutePortAckRecv msg;
  bzero(&msg, sizeof(msg));
  msg.header.msgh_size = sizeof(msg);
  msg.header.msgh_local_port = port;
  kern_return_t kr = mach_msg(&msg.header, MACH_RCV_MSG, 0,
      msg.header.msgh_size, port,
      TestTimeouts::tiny_timeout().InMilliseconds(), MACH_PORT_NULL);
  EXPECT_EQ(KERN_SUCCESS, kr);

  EXPECT_EQ(0, strncmp(kSubstituteAck, msg.buf, sizeof(msg.buf)));
}

MULTIPROCESS_TEST_MAIN(DefaultRuleAllow) {
  [[NSDistributedNotificationCenter defaultCenter]
      postNotificationName:kTestNotification
                    object:[NSString stringWithFormat:@"%d", getpid()]];

  mach_port_t port = MACH_PORT_NULL;
  CHECK_EQ(BOOTSTRAP_UNKNOWN_SERVICE, bootstrap_look_up(bootstrap_port,
      const_cast<char*>(kDefaultRuleTestDeny), &port));
  CHECK(port == MACH_PORT_NULL);

  CHECK_EQ(KERN_SUCCESS, bootstrap_look_up(bootstrap_port,
      const_cast<char*>(kDefaultRuleTestAllow), &port));
  CHECK(port != MACH_PORT_NULL);

  struct SubstitutePortAckSend msg;
  bzero(&msg, sizeof(msg));
  msg.header.msgh_size = sizeof(msg);
  msg.header.msgh_remote_port = port;
  msg.header.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MOVE_SEND);
  strncpy(msg.buf, kSubstituteAck, sizeof(msg.buf));

  CHECK_EQ(KERN_SUCCESS, mach_msg_send(&msg.header));

  return 0;
}

TEST_F(BootstrapSandboxTest, ChildOutliveSandbox) {
  if (base::mac::IsAtLeastOS10_12()) {
    LOG(ERROR) << "BootstrapSandbox does not work on macOS Sierra or later.";
    return;
  }

  const int kTestPolicyId = 1;
  mach_port_t task = mach_task_self();

  // Create a server port.
  mach_port_t port;
  ASSERT_EQ(KERN_SUCCESS, mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE,
      &port));
  base::mac::ScopedMachReceiveRight scoped_port_recv(port);

  ASSERT_EQ(KERN_SUCCESS, mach_port_insert_right(task, port, port,
      MACH_MSG_TYPE_MAKE_SEND));
  base::mac::ScopedMachSendRight scoped_port_send(port);

  // Set up the policy and register the port.
  BootstrapSandboxPolicy policy(BaselinePolicy());
  policy.rules["sync"] = Rule(port);
  sandbox_->RegisterSandboxPolicy(kTestPolicyId, policy);

  // Launch the child.
  std::unique_ptr<PreExecDelegate> pre_exec_delegate(
      sandbox_->NewClient(kTestPolicyId));
  base::LaunchOptions options;
  options.pre_exec_delegate = pre_exec_delegate.get();
  base::Process process = SpawnChildWithOptions("ChildOutliveSandbox", options);
  ASSERT_TRUE(process.IsValid());

  // Synchronize with the child.
  mach_msg_empty_rcv_t rcv_msg;
  bzero(&rcv_msg, sizeof(rcv_msg));
  kern_return_t kr = mach_msg(&rcv_msg.header, MACH_RCV_MSG, 0,
      sizeof(rcv_msg), port,
      TestTimeouts::tiny_timeout().InMilliseconds(), MACH_PORT_NULL);
  ASSERT_EQ(KERN_SUCCESS, kr) << mach_error_string(kr);

  // Destroy the sandbox.
  sandbox_.reset();

  // Synchronize again with the child.
  mach_msg_empty_send_t send_msg;
  bzero(&send_msg, sizeof(send_msg));
  send_msg.header.msgh_size = sizeof(send_msg);
  send_msg.header.msgh_remote_port = rcv_msg.header.msgh_remote_port;
  send_msg.header.msgh_bits =
      MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MOVE_SEND_ONCE);
  kr = mach_msg(&send_msg.header, MACH_SEND_MSG, send_msg.header.msgh_size, 0,
      MACH_PORT_NULL, TestTimeouts::tiny_timeout().InMilliseconds(),
      MACH_PORT_NULL);
  EXPECT_EQ(KERN_SUCCESS, kr) << mach_error_string(kr);

  int code = 0;
  EXPECT_TRUE(process.WaitForExit(&code));
  EXPECT_EQ(0, code);
}

MULTIPROCESS_TEST_MAIN(ChildOutliveSandbox) {
  // Get the synchronization channel.
  mach_port_t port = MACH_PORT_NULL;
  CHECK_EQ(KERN_SUCCESS, bootstrap_look_up(bootstrap_port, "sync", &port));

  // Create a reply port.
  mach_port_t reply_port;
  CHECK_EQ(KERN_SUCCESS, mach_port_allocate(mach_task_self(),
      MACH_PORT_RIGHT_RECEIVE, &reply_port));
  base::mac::ScopedMachReceiveRight scoped_reply_port(reply_port);

  // Send a message to shutdown the sandbox.
  mach_msg_empty_send_t send_msg;
  bzero(&send_msg, sizeof(send_msg));
  send_msg.header.msgh_size = sizeof(send_msg);
  send_msg.header.msgh_local_port = reply_port;
  send_msg.header.msgh_remote_port = port;
  send_msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND,
                                             MACH_MSG_TYPE_MAKE_SEND_ONCE);
  kern_return_t kr = mach_msg_send(&send_msg.header);
  MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_msg_send";

  // Flood the server's message queue with messages. There should be some
  // pending when the sandbox is destroyed.
  for (int i = 0; i < 20; ++i) {
    mach_port_t tmp = MACH_PORT_NULL;
    std::string name = base::StringPrintf("test.%d", i);
    bootstrap_look_up(bootstrap_port, const_cast<char*>(name.c_str()), &tmp);
  }

  // Ack that the sandbox has been shutdown.
  mach_msg_empty_rcv_t rcv_msg;
  bzero(&rcv_msg, sizeof(rcv_msg));
  rcv_msg.header.msgh_size = sizeof(rcv_msg);
  rcv_msg.header.msgh_local_port = reply_port;
  kr = mach_msg_receive(&rcv_msg.header);
  MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_msg_receive";

  // Try to message the sandbox.
  bootstrap_look_up(bootstrap_port, "test", &port);

  return 0;
}

}  // namespace sandbox
