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

#include <Availability.h>

#include <limits>

#include "base/apple/mach_logging.h"
#include "base/logging.h"
#include "build/build_config.h"
#include "util/misc/clock.h"
#include "util/misc/implicit_cast.h"

#if BUILDFLAG(IS_MAC)
#include <bsm/libbsm.h>
#endif  // BUILDFLAG(IS_MAC)

namespace crashpad {

namespace {

constexpr int kNanosecondsPerMillisecond = 1E6;

// TimerRunning() determines whether |deadline| has passed. If |deadline| is
// kMachMessageDeadlineWaitIndefinitely, |*timeout_options| is set to
// MACH_MSG_OPTION_NONE, |*remaining_ms| is set to MACH_MSG_TIMEOUT_NONE, and
// this function returns true. When used with mach_msg(), this will cause
// indefinite waiting. In any other case, |*timeout_options| is set to
// MACH_SEND_TIMEOUT | MACH_RCV_TIMEOUT, so mach_msg() will enforce a timeout
// specified by |*remaining_ms|. If |deadline| is in the future, |*remaining_ms|
// is set to the number of milliseconds remaining, which will always be a
// positive value, and this function returns true. If |deadline| is
// kMachMessageDeadlineNonblocking (indicating that no timer is in effect),
// |*remaining_ms| is set to zero and this function returns true. Otherwise,
// this function sets |*remaining_ms| to zero and returns false.
bool TimerRunning(uint64_t deadline,
                  mach_msg_timeout_t* remaining_ms,
                  mach_msg_option_t* timeout_options) {
  if (deadline == kMachMessageDeadlineWaitIndefinitely) {
    *remaining_ms = MACH_MSG_TIMEOUT_NONE;
    *timeout_options = MACH_MSG_OPTION_NONE;
    return true;
  }

  *timeout_options = MACH_SEND_TIMEOUT | MACH_RCV_TIMEOUT;

  if (deadline == kMachMessageDeadlineNonblocking) {
    *remaining_ms = 0;
    return true;
  }

  uint64_t now = ClockMonotonicNanoseconds();

  if (now >= deadline) {
    *remaining_ms = 0;
  } else {
    uint64_t remaining = deadline - now;

    // Round to the nearest millisecond, taking care not to overflow.
    constexpr int kHalfMillisecondInNanoseconds =
        kNanosecondsPerMillisecond / 2;
    if (remaining <=
        std::numeric_limits<uint64_t>::max() - kHalfMillisecondInNanoseconds) {
      *remaining_ms = (remaining + kHalfMillisecondInNanoseconds) /
                      kNanosecondsPerMillisecond;
    } else {
      *remaining_ms = remaining / kNanosecondsPerMillisecond;
    }
  }

  return *remaining_ms != 0;
}

// This is an internal implementation detail of MachMessageWithDeadline(). It
// determines whether |deadline| has expired, and what timeout value and
// timeout-related options to pass to mach_msg() based on the value of
// |deadline|. mach_msg() will only be called if TimerRunning() returns true or
// if run_even_if_expired is true.
mach_msg_return_t MachMessageWithDeadlineInternal(mach_msg_header_t* message,
                                                  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_timeout_t remaining_ms;
  mach_msg_option_t timeout_options;
  if (!TimerRunning(deadline, &remaining_ms, &timeout_options) &&
      !run_even_if_expired) {
    // Simulate the timed-out return values from mach_msg().
    if (options & MACH_SEND_MSG) {
      return MACH_SEND_TIMED_OUT;
    }
    if (options & MACH_RCV_MSG) {
      return MACH_RCV_TIMED_OUT;
    }
    return MACH_MSG_SUCCESS;
  }

  // Turn off the passed-in timeout bits and replace them with the ones from
  // TimerRunning(). Get the send_size value from message->msgh_size if sending
  // a message.
  return mach_msg(
      message,
      (options & ~(MACH_SEND_TIMEOUT | MACH_RCV_TIMEOUT)) | timeout_options,
      options & MACH_SEND_MSG ? message->msgh_size : 0,
      receive_size,
      receive_port,
      remaining_ms,
      notify_port);
}

}  // namespace

MachMessageDeadline MachMessageDeadlineFromTimeout(
    mach_msg_timeout_t timeout_ms) {
  switch (timeout_ms) {
    case kMachMessageTimeoutNonblocking:
      return kMachMessageDeadlineNonblocking;
    case kMachMessageTimeoutWaitIndefinitely:
      return kMachMessageDeadlineWaitIndefinitely;
    default:
      return ClockMonotonicNanoseconds() +
             implicit_cast<uint64_t>(timeout_ms) * kNanosecondsPerMillisecond;
  }
}

mach_msg_return_t MachMessageWithDeadline(mach_msg_header_t* message,
                                          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() actaully does return MACH_MSG_SUCCESS when not asked to send or
  // receive anything. See 10.9.5 xnu-1504.15.3/osfmk/ipc/mach_msg.c
  // mach_msg_overwrite_trap().
  mach_msg_return_t mr = MACH_MSG_SUCCESS;

  // Break up the send and receive into separate operations, so that the timeout
  // can be recomputed from the deadline for each. Otherwise, the computed
  // timeout will apply individually to the send and then to the receive, and
  // the desired deadline could be exceeded.
  //
  // During sends, always set MACH_SEND_INTERRUPT, and during receives, always
  // set MACH_RCV_INTERRUPT. If the caller didn’t specify these options, the
  // calls will be retried with a recomputed deadline. If these bits weren’t
  // set, the libsyscall wrapper (10.9.5
  // xnu-2422.115.4/libsyscall/mach/mach_msg.c mach_msg() would restart
  // interrupted calls with the original timeout value computed from the
  // deadline, which would no longer correspond to the actual deadline. If the
  // caller did specify these bits, don’t restart anything, because the caller
  // wants to be notified of any interrupted calls.

  if (options & MACH_SEND_MSG) {
    do {
      mr = MachMessageWithDeadlineInternal(
          message,
          (options & ~MACH_RCV_MSG) | MACH_SEND_INTERRUPT,
          0,
          MACH_PORT_NULL,
          deadline,
          notify_port,
          run_even_if_expired);
    } while (mr == MACH_SEND_INTERRUPTED && !(options & MACH_SEND_INTERRUPT));

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

  if (options & MACH_RCV_MSG) {
    do {
      mr = MachMessageWithDeadlineInternal(
          message,
          (options & ~MACH_SEND_MSG) | MACH_RCV_INTERRUPT,
          receive_size,
          receive_port,
          deadline,
          notify_port,
          run_even_if_expired);
    } while (mr == MACH_RCV_INTERRUPTED && !(options & MACH_RCV_INTERRUPT));
  }

  return mr;
}

void PrepareMIGReplyFromRequest(const mach_msg_header_t* in_header,
                                mach_msg_header_t* out_header) {
  out_header->msgh_bits =
      MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(in_header->msgh_bits), 0);
  out_header->msgh_size = sizeof(mig_reply_error_t);
  out_header->msgh_remote_port = in_header->msgh_remote_port;
  out_header->msgh_local_port = MACH_PORT_NULL;
  out_header->msgh_reserved = 0;
  out_header->msgh_id = in_header->msgh_id + 100;
  reinterpret_cast<mig_reply_error_t*>(out_header)->NDR = NDR_record;
}

void SetMIGReplyError(mach_msg_header_t* out_header, kern_return_t error) {
  reinterpret_cast<mig_reply_error_t*>(out_header)->RetCode = error;
}

const mach_msg_trailer_t* MachMessageTrailerFromHeader(
    const mach_msg_header_t* header) {
  vm_address_t header_address = reinterpret_cast<vm_address_t>(header);
  vm_address_t trailer_address = header_address + round_msg(header->msgh_size);
  return reinterpret_cast<const mach_msg_trailer_t*>(trailer_address);
}

bool MachMessageDestroyReceivedPort(mach_port_t port,
                                    mach_msg_type_name_t port_right_type) {
  // This implements a subset of 10.10.5
  // xnu-2782.40.9/libsyscall/mach/mach_msg.c mach_msg_destroy_port() that deals
  // only with port rights that can be received in Mach messages.
  switch (port_right_type) {
    case MACH_MSG_TYPE_PORT_RECEIVE: {
      kern_return_t kr = mach_port_mod_refs(
          mach_task_self(), port, MACH_PORT_RIGHT_RECEIVE, -1);
      if (kr != KERN_SUCCESS) {
        MACH_LOG(ERROR, kr) << "mach_port_mod_refs";
        return false;
      }
      return true;
    }

    case MACH_MSG_TYPE_PORT_SEND:
    case MACH_MSG_TYPE_PORT_SEND_ONCE: {
      kern_return_t kr = mach_port_deallocate(mach_task_self(), port);
      if (kr != KERN_SUCCESS) {
        MACH_LOG(ERROR, kr) << "mach_port_deallocate";
        return false;
      }
      return true;
    }

    default: {
      LOG(ERROR) << "unexpected port right type " << port_right_type;
      return false;
    }
  }
}

#if BUILDFLAG(IS_MAC)

pid_t AuditPIDFromMachMessageTrailer(const mach_msg_trailer_t* trailer) {
  if (trailer->msgh_trailer_type != MACH_MSG_TRAILER_FORMAT_0) {
    LOG(ERROR) << "unexpected msgh_trailer_type " << trailer->msgh_trailer_type;
    return -1;
  }
  if (trailer->msgh_trailer_size <
      REQUESTED_TRAILER_SIZE(kMachMessageReceiveAuditTrailer)) {
    LOG(ERROR) << "small msgh_trailer_size " << trailer->msgh_trailer_size;
    return -1;
  }

  const mach_msg_audit_trailer_t* audit_trailer =
      reinterpret_cast<const mach_msg_audit_trailer_t*>(trailer);

#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8
  pid_t audit_pid;
  audit_token_to_au32(audit_trailer->msgh_audit,
                      nullptr,
                      nullptr,
                      nullptr,
                      nullptr,
                      nullptr,
                      &audit_pid,
                      nullptr,
                      nullptr);
#else
  pid_t audit_pid = audit_token_to_pid(audit_trailer->msgh_audit);
#endif

  return audit_pid;
}

#endif  // BUILDFLAG(IS_MAC)

}  // namespace crashpad
