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

#include <string.h>

#include <limits>

#include "base/apple/mach_logging.h"
#include "base/apple/scoped_mach_vm.h"
#include "base/check_op.h"
#include "base/logging.h"
#include "util/mach/mach_message.h"

namespace crashpad {

namespace {

//! \brief Manages a dynamically-allocated buffer to be used for Mach messaging.
class MachMessageBuffer {
 public:
  MachMessageBuffer() : vm_() {}

  MachMessageBuffer(const MachMessageBuffer&) = delete;
  MachMessageBuffer& operator=(const MachMessageBuffer&) = delete;

  ~MachMessageBuffer() {}

  //! \return A pointer to the buffer.
  mach_msg_header_t* Header() const {
    return reinterpret_cast<mach_msg_header_t*>(vm_.address());
  }

  //! \brief Ensures that this object has a buffer of exactly \a size bytes
  //!     available.
  //!
  //! If the existing buffer is a different size, it will be reallocated without
  //! copying any of the old buffer’s contents to the new buffer. The contents
  //! of the buffer are unspecified after this call, even if no reallocation is
  //! performed.
  kern_return_t Reallocate(vm_size_t size) {
    // This test uses == instead of > so that a large reallocation to receive a
    // large message doesn’t cause permanent memory bloat for the duration of
    // a MachMessageServer::Run() loop.
    if (size != vm_.size()) {
      // reset() first, so that two allocations don’t exist simultaneously.
      vm_.reset();

      if (size) {
        vm_address_t address;
        kern_return_t kr =
            vm_allocate(mach_task_self(),
                        &address,
                        size,
                        VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_MACH_MSG));
        if (kr != KERN_SUCCESS) {
          return kr;
        }

        vm_.reset(address, size);
      }
    }

#if !defined(NDEBUG)
    // Regardless of whether the allocation was changed, scribble over the
    // memory to make sure that nothing relies on zero-initialization or stale
    // contents.
    memset(Header(), 0x66, size);
#endif

    return KERN_SUCCESS;
  }

 private:
  base::apple::ScopedMachVM vm_;
};

// Wraps MachMessageWithDeadline(), using a MachMessageBuffer argument which
// will be resized to |receive_size| (after being page-rounded). MACH_RCV_MSG
// is always combined into |options|.
mach_msg_return_t MachMessageAllocateReceive(MachMessageBuffer* request,
                                             mach_msg_option_t options,
                                             mach_msg_size_t receive_size,
                                             mach_port_name_t receive_port,
                                             MachMessageDeadline deadline,
                                             mach_port_name_t notify_port,
                                             bool run_even_if_expired) {
  mach_msg_size_t request_alloc = round_page(receive_size);
  kern_return_t kr = request->Reallocate(request_alloc);
  if (kr != KERN_SUCCESS) {
    return kr;
  }

  return MachMessageWithDeadline(request->Header(),
                                 options | MACH_RCV_MSG,
                                 receive_size,
                                 receive_port,
                                 deadline,
                                 notify_port,
                                 run_even_if_expired);
}

}  // namespace

// This method implements a server similar to 10.9.4
// xnu-2422.110.17/libsyscall/mach/mach_msg.c mach_msg_server_once(). The server
// callback function and |max_size| parameter have been replaced with a C++
// interface. The |persistent| parameter has been added, allowing this method to
// serve as a stand-in for mach_msg_server(). The |timeout_ms| parameter has
// been added, allowing this function to not block indefinitely.
//
// static
mach_msg_return_t MachMessageServer::Run(Interface* interface,
                                         mach_port_t receive_port,
                                         mach_msg_options_t options,
                                         Persistent persistent,
                                         ReceiveLarge receive_large,
                                         mach_msg_timeout_t timeout_ms) {
  options &= ~(MACH_RCV_MSG | MACH_SEND_MSG);

  const MachMessageDeadline deadline =
      MachMessageDeadlineFromTimeout(timeout_ms);

  if (receive_large == kReceiveLargeResize) {
    options |= MACH_RCV_LARGE;
  } else {
    options &= ~MACH_RCV_LARGE;
  }

  const mach_msg_size_t trailer_alloc = REQUESTED_TRAILER_SIZE(options);
  const mach_msg_size_t expected_receive_size =
      round_msg(interface->MachMessageServerRequestSize()) + trailer_alloc;
  const mach_msg_size_t request_size = (receive_large == kReceiveLargeResize)
                                           ? round_page(expected_receive_size)
                                           : expected_receive_size;
  DCHECK_GE(request_size, sizeof(mach_msg_empty_rcv_t));

  // mach_msg_server() and mach_msg_server_once() would consider whether
  // |options| contains MACH_SEND_TRAILER and include MAX_TRAILER_SIZE in this
  // computation if it does, but that option is ineffective on macOS.
  const mach_msg_size_t reply_size = interface->MachMessageServerReplySize();
  DCHECK_GE(reply_size, sizeof(mach_msg_empty_send_t));
  const mach_msg_size_t reply_alloc = round_page(reply_size);

  MachMessageBuffer request;
  MachMessageBuffer reply;
  bool received_any_request = false;
  bool retry;

  kern_return_t kr;

  do {
    retry = false;

    kr = MachMessageAllocateReceive(&request,
                                    options,
                                    request_size,
                                    receive_port,
                                    deadline,
                                    MACH_PORT_NULL,
                                    !received_any_request);
    if (kr == MACH_RCV_TOO_LARGE) {
      switch (receive_large) {
        case kReceiveLargeError:
          break;

        case kReceiveLargeIgnore:
          // Try again, even in one-shot mode. The caller is expecting this
          // method to take action on the first message in the queue, and has
          // indicated that they want large messages to be ignored. The
          // alternatives, which might involve returning MACH_MSG_SUCCESS,
          // MACH_RCV_TIMED_OUT, or MACH_RCV_TOO_LARGE to a caller that
          // specified one-shot behavior, all seem less correct than retrying.
          MACH_LOG(WARNING, kr) << "mach_msg: ignoring large message";
          retry = true;
          continue;

        case kReceiveLargeResize: {
          mach_msg_size_t this_request_size = round_page(
              round_msg(request.Header()->msgh_size) + trailer_alloc);
          DCHECK_GT(this_request_size, request_size);

          kr = MachMessageAllocateReceive(&request,
                                          options & ~MACH_RCV_LARGE,
                                          this_request_size,
                                          receive_port,
                                          deadline,
                                          MACH_PORT_NULL,
                                          !received_any_request);

          break;
        }
      }
    }

    if (kr != MACH_MSG_SUCCESS) {
      return kr;
    }

    received_any_request = true;

    kr = reply.Reallocate(reply_alloc);
    if (kr != KERN_SUCCESS) {
      return kr;
    }

    mach_msg_header_t* request_header = request.Header();
    mach_msg_header_t* reply_header = reply.Header();
    bool destroy_complex_request = false;
    interface->MachMessageServerFunction(
        request_header, reply_header, &destroy_complex_request);

    if (!(reply_header->msgh_bits & MACH_MSGH_BITS_COMPLEX)) {
      // This only works if the reply message is not complex, because otherwise,
      // the location of the RetCode field is not known. It should be possible
      // to locate the RetCode field by looking beyond the descriptors in a
      // complex reply message, but this is not currently done. This behavior
      // has not proven itself necessary in practice, and it’s not done by
      // mach_msg_server() or mach_msg_server_once() either.
      mig_reply_error_t* reply_mig =
          reinterpret_cast<mig_reply_error_t*>(reply_header);
      if (reply_mig->RetCode == MIG_NO_REPLY) {
        reply_header->msgh_remote_port = MACH_PORT_NULL;
      } else if (reply_mig->RetCode != KERN_SUCCESS &&
                 request_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
        destroy_complex_request = true;
      }
    }

    if (destroy_complex_request &&
        request_header->msgh_bits & MACH_MSGH_BITS_COMPLEX) {
      request_header->msgh_remote_port = MACH_PORT_NULL;
      mach_msg_destroy(request_header);
    }

    if (reply_header->msgh_remote_port != MACH_PORT_NULL) {
      // Avoid blocking indefinitely. This duplicates the logic in 10.9.5
      // xnu-2422.115.4/libsyscall/mach/mach_msg.c mach_msg_server_once(),
      // although the special provision for sending to a send-once right is not
      // made, because kernel keeps sends to a send-once right on the fast path
      // without considering the user-specified timeout. See 10.9.5
      // xnu-2422.115.4/osfmk/ipc/ipc_mqueue.c ipc_mqueue_send().
      const MachMessageDeadline send_deadline =
          deadline == kMachMessageDeadlineWaitIndefinitely
              ? kMachMessageDeadlineNonblocking
              : deadline;

      kr = MachMessageWithDeadline(reply_header,
                                   options | MACH_SEND_MSG,
                                   0,
                                   MACH_PORT_NULL,
                                   send_deadline,
                                   MACH_PORT_NULL,
                                   true);

      if (kr != MACH_MSG_SUCCESS) {
        if (kr == MACH_SEND_INVALID_DEST ||
            kr == MACH_SEND_TIMED_OUT ||
            kr == MACH_SEND_INTERRUPTED) {
          mach_msg_destroy(reply_header);
        }
        return kr;
      }
    }
  } while (persistent == kPersistent || retry);

  return kr;
}

}  // namespace crashpad
