// Copyright 2017 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/linux/exception_handler_client.h"

#include <errno.h>
#include <signal.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <unistd.h>

#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "build/build_config.h"
#include "third_party/lss/lss.h"
#include "util/file/file_io.h"
#include "util/linux/ptrace_broker.h"
#include "util/linux/socket.h"
#include "util/misc/from_pointer_cast.h"
#include "util/posix/signals.h"

#if defined(OS_ANDROID)
#include <android/api-level.h>
#endif

namespace crashpad {

namespace {

class ScopedSigprocmaskRestore {
 public:
  explicit ScopedSigprocmaskRestore(const kernel_sigset_t& set_to_block)
      : orig_mask_(), mask_is_set_(false) {
    mask_is_set_ = sys_sigprocmask(SIG_BLOCK, &set_to_block, &orig_mask_) == 0;
    DPLOG_IF(ERROR, !mask_is_set_) << "sigprocmask";
  }

  ~ScopedSigprocmaskRestore() {
    if (mask_is_set_ &&
        sys_sigprocmask(SIG_SETMASK, &orig_mask_, nullptr) != 0) {
      DPLOG(ERROR) << "sigprocmask";
    }
  }

 private:
  kernel_sigset_t orig_mask_;
  bool mask_is_set_;

  DISALLOW_COPY_AND_ASSIGN(ScopedSigprocmaskRestore);
};

}  // namespace

ExceptionHandlerClient::ExceptionHandlerClient(int sock, bool multiple_clients)
    : server_sock_(sock),
      ptracer_(-1),
      can_set_ptracer_(true),
      multiple_clients_(multiple_clients) {}

ExceptionHandlerClient::~ExceptionHandlerClient() = default;

bool ExceptionHandlerClient::GetHandlerCredentials(ucred* creds) {
  ExceptionHandlerProtocol::ClientToServerMessage message = {};
  message.type =
      ExceptionHandlerProtocol::ClientToServerMessage::kTypeCheckCredentials;
  if (UnixCredentialSocket::SendMsg(server_sock_, &message, sizeof(message)) !=
      0) {
    return false;
  }

  ExceptionHandlerProtocol::ServerToClientMessage response;
  return UnixCredentialSocket::RecvMsg(
      server_sock_, &response, sizeof(response), creds);
}

#if defined(STARBOARD)
bool ExceptionHandlerClient::SendEvergreenInfo(
    const ExceptionHandlerProtocol::ClientInformation& info) {
  return SendEvergreenInfoRequest(info);
}

bool ExceptionHandlerClient::SendAnnotations(
    const ExceptionHandlerProtocol::ClientInformation& info) {
  return SendAddAnnotationsRequest(info);
}
#endif

int ExceptionHandlerClient::RequestCrashDump(
    const ExceptionHandlerProtocol::ClientInformation& info) {
  VMAddress sp = FromPointerCast<VMAddress>(&sp);

  if (multiple_clients_) {
    return SignalCrashDump(info, sp);
  }

  int status = SendCrashDumpRequest(info, sp);
  if (status != 0) {
    return status;
  }
  return WaitForCrashDumpComplete();
}

int ExceptionHandlerClient::SetPtracer(pid_t pid) {
  if (ptracer_ == pid) {
    return 0;
  }

  if (!can_set_ptracer_) {
    return EPERM;
  }

  if (prctl(PR_SET_PTRACER, pid, 0, 0, 0) == 0) {
    return 0;
  }
  return errno;
}

void ExceptionHandlerClient::SetCanSetPtracer(bool can_set_ptracer) {
  can_set_ptracer_ = can_set_ptracer;
}

int ExceptionHandlerClient::SignalCrashDump(
    const ExceptionHandlerProtocol::ClientInformation& info,
    VMAddress stack_pointer) {
  kernel_sigset_t dump_done_sigset;
  sys_sigemptyset(&dump_done_sigset);
  sys_sigaddset(&dump_done_sigset, ExceptionHandlerProtocol::kDumpDoneSignal);
  ScopedSigprocmaskRestore scoped_block(dump_done_sigset);

  int status = SendCrashDumpRequest(info, stack_pointer);
  if (status != 0) {
    return status;
  }

  siginfo_t siginfo = {};
  timespec timeout;
  timeout.tv_sec = 5;
  timeout.tv_nsec = 0;
  if (HANDLE_EINTR(sys_sigtimedwait(&dump_done_sigset, &siginfo, &timeout)) <
      0) {
    return errno;
  }

  return 0;
}

#if defined(STARBOARD)
bool ExceptionHandlerClient::SendEvergreenInfoRequest(
    const ExceptionHandlerProtocol::ClientInformation& info) {
  ExceptionHandlerProtocol::ClientToServerMessage message;
  message.type =
      ExceptionHandlerProtocol::ClientToServerMessage::kTypeAddEvergreenInfo;
  message.client_info = info;

  UnixCredentialSocket::SendMsg(server_sock_, &message, sizeof(message));
  return true;
}

bool ExceptionHandlerClient::SendAddAnnotationsRequest(
    const ExceptionHandlerProtocol::ClientInformation& info) {
  ExceptionHandlerProtocol::ClientToServerMessage message;
  message.type =
      ExceptionHandlerProtocol::ClientToServerMessage::kTypeAddAnnotations;
  message.client_info = info;

  UnixCredentialSocket::SendMsg(server_sock_, &message, sizeof(message));
  return true;
}
#endif

int ExceptionHandlerClient::SendCrashDumpRequest(
    const ExceptionHandlerProtocol::ClientInformation& info,
    VMAddress stack_pointer) {
  ExceptionHandlerProtocol::ClientToServerMessage message;
  message.type =
      ExceptionHandlerProtocol::ClientToServerMessage::kTypeCrashDumpRequest;
  message.requesting_thread_stack_address = stack_pointer;
  message.client_info = info;
  return UnixCredentialSocket::SendMsg(server_sock_, &message, sizeof(message));
}

int ExceptionHandlerClient::WaitForCrashDumpComplete() {
  ExceptionHandlerProtocol::ServerToClientMessage message;

  // If the server hangs up, ReadFileExactly will return false without setting
  // errno.
  errno = 0;
  while (ReadFileExactly(server_sock_, &message, sizeof(message))) {
    switch (message.type) {
      case ExceptionHandlerProtocol::ServerToClientMessage::kTypeForkBroker: {
        Signals::InstallDefaultHandler(SIGCHLD);

        pid_t pid = fork();
        if (pid <= 0) {
          ExceptionHandlerProtocol::Errno error = pid < 0 ? errno : 0;
          if (!WriteFile(server_sock_, &error, sizeof(error))) {
            return errno;
          }
        }

        if (pid < 0) {
          continue;
        }

        if (pid == 0) {
#if defined(ARCH_CPU_64_BITS)
          constexpr bool am_64_bit = true;
#else
          constexpr bool am_64_bit = false;
#endif  // ARCH_CPU_64_BITS

          PtraceBroker broker(server_sock_, getppid(), am_64_bit);
          _exit(broker.Run());
        }

        int status = 0;
        pid_t child = HANDLE_EINTR(waitpid(pid, &status, 0));
        DCHECK_EQ(child, pid);

        if (child == pid && status != 0) {
          return status;
        }
        continue;
      }

      case ExceptionHandlerProtocol::ServerToClientMessage::kTypeSetPtracer: {
        ExceptionHandlerProtocol::Errno result = SetPtracer(message.pid);
        if (!WriteFile(server_sock_, &result, sizeof(result))) {
          return errno;
        }
        continue;
      }

      case ExceptionHandlerProtocol::ServerToClientMessage::kTypeCredentials:
        DCHECK(false);
        continue;

      case ExceptionHandlerProtocol::ServerToClientMessage::
          kTypeCrashDumpComplete:
      case ExceptionHandlerProtocol::ServerToClientMessage::
          kTypeCrashDumpFailed:
        return 0;
    }

    DCHECK(false);
  }

  return errno;
}

}  // namespace crashpad
