// Copyright 2014 The Crashpad Authors. All rights reserved.
//
// 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/logging.h"
#include "base/mac/mach_logging.h"
#include "util/misc/clock.h"
#include "util/misc/implicit_cast.h"

#if defined(OS_MAC)
#include <bsm/libbsm.h>
#endif  // OS_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 defined(OS_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  // OS_MAC

}  // namespace crashpad
