// 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 "util/mach/notify_server.h"

#include <stddef.h>

#include "base/apple/scoped_mach_port.h"
#include "base/compiler_specific.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "test/mac/mach_errors.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"

namespace crashpad {
namespace test {
namespace {

using testing::AllOf;
using testing::DoAll;
using testing::Eq;
using testing::Invoke;
using testing::Pointee;
using testing::ResultOf;
using testing::Return;
using testing::SetArgPointee;
using testing::StrictMock;
using testing::WithArg;

//! \brief Adds a send right to an existing receive right.
//!
//! \param[in] receive_right The receive right to add a send right to.
//!
//! \return The send right, which will have the same name as the receive right.
//!     On failure, `MACH_PORT_NULL` with a Google Test failure added.
mach_port_t SendRightFromReceiveRight(mach_port_t receive_right) {
  kern_return_t kr = mach_port_insert_right(
      mach_task_self(), receive_right, receive_right, MACH_MSG_TYPE_MAKE_SEND);
  if (kr != KERN_SUCCESS) {
    EXPECT_EQ(kr, KERN_SUCCESS)
        << MachErrorMessage(kr, "mach_port_insert_right");
    return MACH_PORT_NULL;
  }

  return receive_right;
}

//! \brief Extracts a send-once right from a receive right.
//!
//! \param[in] receive_right The receive right to make a send-once right from.
//!
//! \return The send-once right. On failure, `MACH_PORT_NULL` with a Google Test
//!     failure added.
mach_port_t SendOnceRightFromReceiveRight(mach_port_t receive_right) {
  mach_port_t send_once_right;
  mach_msg_type_name_t acquired_type;
  kern_return_t kr = mach_port_extract_right(mach_task_self(),
                                             receive_right,
                                             MACH_MSG_TYPE_MAKE_SEND_ONCE,
                                             &send_once_right,
                                             &acquired_type);
  if (kr != KERN_SUCCESS) {
    EXPECT_EQ(kr, KERN_SUCCESS)
        << MachErrorMessage(kr, "mach_port_extract_right");
    return MACH_PORT_NULL;
  }

  EXPECT_EQ(acquired_type,
            implicit_cast<mach_msg_type_name_t>(MACH_MSG_TYPE_PORT_SEND_ONCE));

  return send_once_right;
}

//! \brief Deallocates a Mach port by calling `mach_port_deallocate()`.
//!
//! This function exists to adapt `mach_port_deallocate()` to a function that
//! accepts a single argument and has no return value. It can be used with the
//! testing::Invoke() Google Mock action.
//!
//! On failure, a Google Test failure will be added.
void MachPortDeallocate(mach_port_t port) {
  kern_return_t kr = mach_port_deallocate(mach_task_self(), port);
  EXPECT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "mach_port_deallocate");
}

//! \brief Determines whether a specific right is held for a Mach port.
//!
//! \param[in] port The port to check for a right.
//! \param[in] right The right to check for.
//!
//! \return `true` if \a port has \a right, `false` otherwise. On faliure,
//!     `false` with a Google Test failure added.
bool IsRight(mach_port_t port, mach_port_type_t right) {
  mach_port_type_t type;
  kern_return_t kr = mach_port_type(mach_task_self(), port, &type);
  if (kr != KERN_SUCCESS) {
    EXPECT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "mach_port_type");
    return false;
  }

  return type & right;
}

//! \brief Determines whether a receive right is held for a Mach port.
//!
//! This is a special single-argument form of IsRight() for ease of use in a
//! Google Mock matcher.
//!
//! \param[in] port The port to check for a receive right.
//!
//! \return `true` if a receive right is held, `false` otherwise. On faliure,
//!     `false` with a Google Test failure added.
bool IsReceiveRight(mach_port_t port) {
  return IsRight(port, MACH_PORT_TYPE_RECEIVE);
}

//! \brief Returns the user reference count for port rights.
//!
//! \param[in] port The port whose user reference count should be returned.
//! \param[in] right The port right to return the user reference count for.
//!
//! \return The user reference count for the specified port and right. On
//!     failure, `-1` with a Google Test failure added.
mach_port_urefs_t RightRefCount(mach_port_t port, mach_port_right_t right) {
  mach_port_urefs_t refs;
  kern_return_t kr = mach_port_get_refs(mach_task_self(), port, right, &refs);
  if (kr != KERN_SUCCESS) {
    EXPECT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "mach_port_get_refs");
    return -1;
  }

  return refs;
}

//! \brief Returns the user reference count for a port’s dead-name rights.
//!
//! This is a special single-argument form of RightRefCount() for ease of use in
//! a Google Mock matcher.
//!
//! \param[in] port The port whose dead-name user reference count should be
//!     returned.
//!
//! \return The user reference count for the port’s dead-name rights. On
//!     failure, `-1` with a Google Test failure added.
mach_port_urefs_t DeadNameRightRefCount(mach_port_t port) {
  return RightRefCount(port, MACH_PORT_RIGHT_DEAD_NAME);
}

class NotifyServerTestBase : public testing::Test,
                             public NotifyServer::Interface {
 public:
  NotifyServerTestBase(const NotifyServerTestBase&) = delete;
  NotifyServerTestBase& operator=(const NotifyServerTestBase&) = delete;

  // NotifyServer::Interface:

  MOCK_METHOD(kern_return_t,
              DoMachNotifyPortDeleted,
              (notify_port_t notify,
               mach_port_name_t name,
               const mach_msg_trailer_t* trailer),
              (override));

  MOCK_METHOD(kern_return_t,
              DoMachNotifyPortDestroyed,
              (notify_port_t notify,
               mach_port_t rights,
               const mach_msg_trailer_t* trailer,
               bool* destroy_request),
              (override));

  MOCK_METHOD(kern_return_t,
              DoMachNotifyNoSenders,
              (notify_port_t notify,
               mach_port_mscount_t mscount,
               const mach_msg_trailer_t* trailer),
              (override));

  MOCK_METHOD(kern_return_t,
              DoMachNotifySendOnce,
              (notify_port_t notify, const mach_msg_trailer_t* trailer),
              (override));

  MOCK_METHOD(kern_return_t,
              DoMachNotifyDeadName,
              (notify_port_t notify,
               mach_port_name_t name,
               const mach_msg_trailer_t* trailer),
              (override));

 protected:
  NotifyServerTestBase() : testing::Test(), NotifyServer::Interface() {}

  ~NotifyServerTestBase() override {}

  //! \brief Requests a Mach port notification.
  //!
  //! \a name, \a variant, and \a sync are passed as-is to
  //! `mach_port_request_notification()`. The notification will be sent to a
  //! send-once right made from ServerPort(). Any previous send right for the
  //! notification will be deallocated.
  //!
  //! \return `true` on success, `false` on failure with a Google Test failure
  //!     added.
  bool RequestMachPortNotification(mach_port_t name,
                                   mach_msg_id_t variant,
                                   mach_port_mscount_t sync) {
    mach_port_t previous;
    kern_return_t kr =
        mach_port_request_notification(mach_task_self(),
                                       name,
                                       variant,
                                       sync,
                                       ServerPort(),
                                       MACH_MSG_TYPE_MAKE_SEND_ONCE,
                                       &previous);
    if (kr != KERN_SUCCESS) {
      EXPECT_EQ(kr, KERN_SUCCESS)
          << MachErrorMessage(kr, "mach_port_request_notification");
      return false;
    }

    base::apple::ScopedMachSendRight previous_owner(previous);
    EXPECT_EQ(previous, kMachPortNull);

    return true;
  }

  //! \brief Runs a NotifyServer Mach message server.
  //!
  //! The server will listen on ServerPort() in persistent nonblocking mode, and
  //! dispatch received messages to the appropriate NotifyServer::Interface
  //! method. Google Mock expectations check that the proper method, if any, is
  //! called exactly once, and that no undesired methods are called.
  //!
  //! MachMessageServer::Run() is expected to return `MACH_RCV_TIMED_OUT`,
  //! because it runs in persistent nonblocking mode. If it returns anything
  //! else, a Google Test assertion is added.
  void RunServer() {
    NotifyServer notify_server(this);
    mach_msg_return_t mr =
        MachMessageServer::Run(&notify_server,
                               ServerPort(),
                               kMachMessageReceiveAuditTrailer,
                               MachMessageServer::kPersistent,
                               MachMessageServer::kReceiveLargeError,
                               kMachMessageTimeoutNonblocking);
    ASSERT_EQ(mr, MACH_RCV_TIMED_OUT)
        << MachErrorMessage(mr, "MachMessageServer::Run");
  }

  //! \brief Returns the receive right to be used for the server.
  //!
  //! This receive right is created lazily on a per-test basis. It is destroyed
  //! by TearDown() at the conclusion of each test.
  //!
  //! \return The server port receive right, creating it if one has not yet been
  //!     established for the current test. On failure, returns `MACH_PORT_NULL`
  //!     with a Google Test failure added.
  mach_port_t ServerPort() {
    if (!server_port_.is_valid()) {
      server_port_.reset(NewMachPort(MACH_PORT_RIGHT_RECEIVE));
      EXPECT_TRUE(server_port_.is_valid());
    }

    return server_port_.get();
  }

  // testing::Test:
  void TearDown() override { server_port_.reset(); }

 private:
  base::apple::ScopedMachReceiveRight server_port_;
};

using NotifyServerTest = StrictMock<NotifyServerTestBase>;

TEST_F(NotifyServerTest, Basic) {
  NotifyServer server(this);

  std::set<mach_msg_id_t> expect_request_ids;
  expect_request_ids.insert(MACH_NOTIFY_PORT_DELETED);
  expect_request_ids.insert(MACH_NOTIFY_PORT_DESTROYED);
  expect_request_ids.insert(MACH_NOTIFY_NO_SENDERS);
  expect_request_ids.insert(MACH_NOTIFY_SEND_ONCE);
  expect_request_ids.insert(MACH_NOTIFY_DEAD_NAME);
  EXPECT_EQ(server.MachMessageServerRequestIDs(), expect_request_ids);

  // The port-destroyed notification is the largest request message in the
  // subsystem. <mach/notify.h> defines the same structure, but with a basic
  // trailer, so use offsetof to get the size of the basic structure without any
  // trailer.
  EXPECT_EQ(server.MachMessageServerRequestSize(),
            offsetof(mach_port_destroyed_notification_t, trailer));

  mig_reply_error_t reply;
  EXPECT_EQ(server.MachMessageServerReplySize(), sizeof(reply));
}

// When no notifications are requested, nothing should happen.
TEST_F(NotifyServerTest, NoNotification) {
  RunServer();
}

// When a send-once right with a dead-name notification request is deallocated,
// a port-deleted notification should be generated.
TEST_F(NotifyServerTest, MachNotifyPortDeleted) {
  base::apple::ScopedMachReceiveRight receive_right(
      NewMachPort(MACH_PORT_RIGHT_RECEIVE));
  ASSERT_TRUE(receive_right.is_valid());

  base::apple::ScopedMachSendRight send_once_right(
      SendOnceRightFromReceiveRight(receive_right.get()));
  ASSERT_TRUE(send_once_right.is_valid());

  ASSERT_TRUE(RequestMachPortNotification(
      send_once_right.get(), MACH_NOTIFY_DEAD_NAME, 0));

  EXPECT_CALL(
      *this,
      DoMachNotifyPortDeleted(ServerPort(),
                              send_once_right.get(),
                              ResultOf(AuditPIDFromMachMessageTrailer, 0)))
      .WillOnce(Return(MIG_NO_REPLY))
      .RetiresOnSaturation();

  send_once_right.reset();

  RunServer();
}

// When a receive right with a port-destroyed notification request is destroyed,
// a port-destroyed notification should be generated.
TEST_F(NotifyServerTest, MachNotifyPortDestroyed) {
  base::apple::ScopedMachReceiveRight receive_right(
      NewMachPort(MACH_PORT_RIGHT_RECEIVE));
  ASSERT_TRUE(receive_right.is_valid());

  ASSERT_TRUE(RequestMachPortNotification(
      receive_right.get(), MACH_NOTIFY_PORT_DESTROYED, 0));

  EXPECT_CALL(
      *this,
      DoMachNotifyPortDestroyed(ServerPort(),
                                ResultOf(IsReceiveRight, true),
                                ResultOf(AuditPIDFromMachMessageTrailer, 0),
                                Pointee(Eq(false))))
      .WillOnce(DoAll(SetArgPointee<3>(true), Return(MIG_NO_REPLY)))
      .RetiresOnSaturation();

  receive_right.reset();

  RunServer();
}

// When a receive right with a port-destroyed notification request is not
// destroyed, no port-destroyed notification should be generated.
TEST_F(NotifyServerTest, MachNotifyPortDestroyed_NoNotification) {
  base::apple::ScopedMachReceiveRight receive_right(
      NewMachPort(MACH_PORT_RIGHT_RECEIVE));
  ASSERT_TRUE(receive_right.is_valid());

  ASSERT_TRUE(RequestMachPortNotification(
      receive_right.get(), MACH_NOTIFY_PORT_DESTROYED, 0));

  RunServer();
}

// When a no-senders notification request is registered for a receive right with
// no senders, a no-senders notification should be generated.
TEST_F(NotifyServerTest, MachNotifyNoSenders_NoSendRight) {
  base::apple::ScopedMachReceiveRight receive_right(
      NewMachPort(MACH_PORT_RIGHT_RECEIVE));
  ASSERT_TRUE(receive_right.is_valid());

  ASSERT_TRUE(RequestMachPortNotification(
      receive_right.get(), MACH_NOTIFY_NO_SENDERS, 0));

  EXPECT_CALL(*this,
              DoMachNotifyNoSenders(
                  ServerPort(), 0, ResultOf(AuditPIDFromMachMessageTrailer, 0)))
      .WillOnce(Return(MIG_NO_REPLY))
      .RetiresOnSaturation();

  RunServer();
}

// When the last send right corresponding to a receive right with a no-senders
// notification request is deallocated, a no-senders notification should be
// generated.
TEST_F(NotifyServerTest, MachNotifyNoSenders_SendRightDeallocated) {
  base::apple::ScopedMachReceiveRight receive_right(
      NewMachPort(MACH_PORT_RIGHT_RECEIVE));
  ASSERT_TRUE(receive_right.is_valid());

  base::apple::ScopedMachSendRight send_right(
      SendRightFromReceiveRight(receive_right.get()));
  ASSERT_TRUE(send_right.is_valid());

  ASSERT_TRUE(RequestMachPortNotification(
      receive_right.get(), MACH_NOTIFY_NO_SENDERS, 1));

  EXPECT_CALL(*this,
              DoMachNotifyNoSenders(
                  ServerPort(), 1, ResultOf(AuditPIDFromMachMessageTrailer, 0)))
      .WillOnce(Return(MIG_NO_REPLY))
      .RetiresOnSaturation();

  send_right.reset();

  RunServer();
}

// When the a receive right with a no-senders notification request never loses
// all senders, no no-senders notification should be generated.
TEST_F(NotifyServerTest, MachNotifyNoSenders_NoNotification) {
  base::apple::ScopedMachReceiveRight receive_right(
      NewMachPort(MACH_PORT_RIGHT_RECEIVE));
  ASSERT_TRUE(receive_right.is_valid());

  base::apple::ScopedMachSendRight send_right_0(
      SendRightFromReceiveRight(receive_right.get()));
  ASSERT_TRUE(send_right_0.is_valid());

  base::apple::ScopedMachSendRight send_right_1(
      SendRightFromReceiveRight(receive_right.get()));
  ASSERT_TRUE(send_right_1.is_valid());

  ASSERT_TRUE(RequestMachPortNotification(
      receive_right.get(), MACH_NOTIFY_NO_SENDERS, 1));

  send_right_1.reset();

  RunServer();

  EXPECT_EQ(RightRefCount(receive_right.get(), MACH_PORT_RIGHT_RECEIVE), 1u);
  EXPECT_EQ(RightRefCount(receive_right.get(), MACH_PORT_RIGHT_SEND), 1u);
}

// When a send-once right is deallocated without being used, a send-once
// notification notification should be sent via the send-once right.
TEST_F(NotifyServerTest, MachNotifySendOnce_ExplicitDeallocation) {
  base::apple::ScopedMachSendRight send_once_right(
      SendOnceRightFromReceiveRight(ServerPort()));
  ASSERT_TRUE(send_once_right.is_valid());

  EXPECT_CALL(*this,
              DoMachNotifySendOnce(ServerPort(),
                                   ResultOf(AuditPIDFromMachMessageTrailer, 0)))
      .WillOnce(Return(MIG_NO_REPLY))
      .RetiresOnSaturation();

  send_once_right.reset();

  RunServer();
}

// When a send-once right is sent to a receiver that never dequeues the message,
// the send-once right is destroyed, and a send-once notification should appear
// on the reply port.
TEST_F(NotifyServerTest, MachNotifySendOnce_ImplicitDeallocation) {
  base::apple::ScopedMachReceiveRight receive_right(
      NewMachPort(MACH_PORT_RIGHT_RECEIVE));
  ASSERT_TRUE(receive_right.is_valid());

  mach_msg_empty_send_t message = {};
  message.header.msgh_bits =
      MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE);
  message.header.msgh_size = sizeof(message);
  message.header.msgh_remote_port = receive_right.get();
  message.header.msgh_local_port = ServerPort();
  mach_msg_return_t mr = mach_msg(&message.header,
                                  MACH_SEND_MSG | MACH_SEND_TIMEOUT,
                                  message.header.msgh_size,
                                  0,
                                  MACH_PORT_NULL,
                                  0,
                                  MACH_PORT_NULL);
  ASSERT_EQ(mr, MACH_MSG_SUCCESS) << MachErrorMessage(mr, "mach_msg");

  EXPECT_CALL(*this,
              DoMachNotifySendOnce(ServerPort(),
                                   ResultOf(AuditPIDFromMachMessageTrailer, 0)))
      .WillOnce(Return(MIG_NO_REPLY))
      .RetiresOnSaturation();

  receive_right.reset();

  RunServer();
}

// When the receive right corresponding to a send-once right with a dead-name
// notification request is destroyed, a dead-name notification should be
// generated.
TEST_F(NotifyServerTest, MachNotifyDeadName) {
  base::apple::ScopedMachReceiveRight receive_right(
      NewMachPort(MACH_PORT_RIGHT_RECEIVE));
  ASSERT_TRUE(receive_right.is_valid());

  base::apple::ScopedMachSendRight send_once_right(
      SendOnceRightFromReceiveRight(receive_right.get()));
  ASSERT_TRUE(send_once_right.is_valid());

  ASSERT_TRUE(RequestMachPortNotification(
      send_once_right.get(), MACH_NOTIFY_DEAD_NAME, 0));

  // send_once_right becomes a dead name with the send-once right’s original
  // user reference count of 1, but the dead-name notification increments the
  // dead-name reference count, so it becomes 2. Take care to deallocate that
  // reference. The original reference is managed by send_once_right_owner.
  EXPECT_CALL(*this,
              DoMachNotifyDeadName(ServerPort(),
                                   AllOf(send_once_right.get(),
                                         ResultOf(DeadNameRightRefCount, 2)),
                                   ResultOf(AuditPIDFromMachMessageTrailer, 0)))
      .WillOnce(
          DoAll(WithArg<1>(Invoke(MachPortDeallocate)), Return(MIG_NO_REPLY)))
      .RetiresOnSaturation();

  receive_right.reset();

  RunServer();

  EXPECT_TRUE(IsRight(send_once_right.get(), MACH_PORT_TYPE_DEAD_NAME));

  EXPECT_EQ(RightRefCount(send_once_right.get(), MACH_PORT_RIGHT_SEND_ONCE),
            0u);
  EXPECT_EQ(DeadNameRightRefCount(send_once_right.get()), 1u);
}

// When the receive right corresponding to a send-once right with a dead-name
// notification request is not destroyed, no dead-name notification should be
// generated.
TEST_F(NotifyServerTest, MachNotifyDeadName_NoNotification) {
  base::apple::ScopedMachReceiveRight receive_right(
      NewMachPort(MACH_PORT_RIGHT_RECEIVE));
  ASSERT_TRUE(receive_right.is_valid());

  base::apple::ScopedMachSendRight send_once_right(
      SendOnceRightFromReceiveRight(receive_right.get()));
  ASSERT_TRUE(send_once_right.is_valid());

  ASSERT_TRUE(RequestMachPortNotification(
      send_once_right.get(), MACH_NOTIFY_DEAD_NAME, 0));

  RunServer();

  EXPECT_FALSE(IsRight(send_once_right.get(), MACH_PORT_TYPE_DEAD_NAME));

  EXPECT_EQ(RightRefCount(send_once_right.get(), MACH_PORT_RIGHT_SEND_ONCE),
            1u);
  EXPECT_EQ(DeadNameRightRefCount(send_once_right.get()), 0u);
}

}  // namespace
}  // namespace test
}  // namespace crashpad
