// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/crash/content/app/crashpad.h"

#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#include <algorithm>

#include "base/environment.h"
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/no_destructor.h"
#include "base/path_service.h"
#include "base/posix/eintr_wrapper.h"
#include "base/posix/global_descriptors.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "components/crash/content/app/crash_reporter_client.h"
#include "content/public/common/content_descriptors.h"
#include "sandbox/linux/services/syscall_wrappers.h"
#include "third_party/crashpad/crashpad/client/annotation.h"
#include "third_party/crashpad/crashpad/client/client_argv_handling.h"
#include "third_party/crashpad/crashpad/client/crashpad_client.h"
#include "third_party/crashpad/crashpad/client/simulate_crash_linux.h"
#include "third_party/crashpad/crashpad/snapshot/sanitized/sanitization_information.h"
#include "third_party/crashpad/crashpad/util/linux/exception_handler_client.h"
#include "third_party/crashpad/crashpad/util/linux/exception_information.h"
#include "third_party/crashpad/crashpad/util/linux/scoped_pr_set_dumpable.h"
#include "third_party/crashpad/crashpad/util/misc/from_pointer_cast.h"
#include "third_party/crashpad/crashpad/util/posix/signals.h"

#if defined(OS_ANDROID)
#include "base/android/build_info.h"
#include "base/android/java_exception_reporter.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/android/path_utils.h"
#include "jni/PackagePaths_jni.h"
#endif  // OS_ANDROID

namespace crashpad {
namespace {

bool SetSanitizationInfo(crash_reporter::CrashReporterClient* client,
                         SanitizationInformation* info) {
  const char* const* whitelist = nullptr;
  void* target_module = nullptr;
  bool sanitize_stacks = false;
  client->GetSanitizationInformation(&whitelist, &target_module,
                                     &sanitize_stacks);
  info->annotations_whitelist_address = FromPointerCast<VMAddress>(whitelist);
  info->target_module_address = FromPointerCast<VMAddress>(target_module);
  info->sanitize_stacks = sanitize_stacks;
  return whitelist != nullptr || target_module != nullptr || sanitize_stacks;
}

void SetExceptionInformation(siginfo_t* siginfo,
                             ucontext_t* context,
                             ExceptionInformation* info) {
  info->siginfo_address =
      FromPointerCast<decltype(info->siginfo_address)>(siginfo);
  info->context_address =
      FromPointerCast<decltype(info->context_address)>(context);
  info->thread_id = sandbox::sys_gettid();
}

void SetClientInformation(ExceptionInformation* exception,
                          SanitizationInformation* sanitization,
                          ClientInformation* info) {
  info->exception_information_address =
      FromPointerCast<decltype(info->exception_information_address)>(exception);

  info->sanitization_information_address =
      FromPointerCast<decltype(info->sanitization_information_address)>(
          sanitization);
}

// A signal handler for non-browser processes in the sandbox.
// Sends a message to a crashpad::CrashHandlerHost to handle the crash.
class SandboxedHandler {
 public:
  static SandboxedHandler* Get() {
    static SandboxedHandler* instance = new SandboxedHandler();
    return instance;
  }

  bool Initialize(bool dump_at_crash) {
    request_dump_ = dump_at_crash ? 1 : 0;

    SetSanitizationInfo(crash_reporter::GetCrashReporterClient(),
                        &sanitization_);
    server_fd_ = base::GlobalDescriptors::GetInstance()->Get(
        service_manager::kCrashDumpSignal);

    return Signals::InstallCrashHandlers(HandleCrash, 0, &old_actions_);
  }

  void HandleCrashNonFatal(int signo, siginfo_t* siginfo, void* context) {
    base::ScopedFD connection;
    if (ConnectToHandler(signo, &connection) == 0) {
      ExceptionInformation exception_information;
      SetExceptionInformation(siginfo, static_cast<ucontext_t*>(context),
                              &exception_information);

      ClientInformation info;
      SetClientInformation(&exception_information, &sanitization_, &info);

      ScopedPrSetDumpable set_dumpable(/* may_log= */ false);

      ExceptionHandlerClient handler_client(connection.get());
      handler_client.SetCanSetPtracer(false);
      handler_client.RequestCrashDump(info);
    }
  }

 private:
  SandboxedHandler() = default;
  ~SandboxedHandler() = delete;

  int ConnectToHandler(int signo, base::ScopedFD* connection) {
    int fds[2];
    if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) != 0) {
      return errno;
    }
    base::ScopedFD local_connection(fds[0]);
    base::ScopedFD handlers_socket(fds[1]);

    // SELinux may block the handler from setting SO_PASSCRED on this socket.
    // Attempt to set it here, but the handler can still try if this fails.
    int optval = 1;
    socklen_t optlen = sizeof(optval);
    setsockopt(handlers_socket.get(), SOL_SOCKET, SO_PASSCRED, &optval, optlen);

    iovec iov[2];
    iov[0].iov_base = &signo;
    iov[0].iov_len = sizeof(signo);
    iov[1].iov_base = &request_dump_;
    iov[1].iov_len = sizeof(request_dump_);

    msghdr msg;
    msg.msg_name = nullptr;
    msg.msg_namelen = 0;
    msg.msg_iov = iov;
    msg.msg_iovlen = base::size(iov);

    char cmsg_buf[CMSG_SPACE(sizeof(int))];
    msg.msg_control = cmsg_buf;
    msg.msg_controllen = sizeof(cmsg_buf);

    cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
    *reinterpret_cast<int*>(CMSG_DATA(cmsg)) = handlers_socket.get();

    if (HANDLE_EINTR(sendmsg(server_fd_, &msg, MSG_NOSIGNAL)) < 0) {
      return errno;
    }

    *connection = std::move(local_connection);
    return 0;
  }

  static void HandleCrash(int signo, siginfo_t* siginfo, void* context) {
    SandboxedHandler* state = Get();
    state->HandleCrashNonFatal(signo, siginfo, context);
    Signals::RestoreHandlerAndReraiseSignalOnReturn(
        siginfo, state->old_actions_.ActionForSignal(signo));
  }

  Signals::OldActions old_actions_ = {};
  SanitizationInformation sanitization_;
  int server_fd_;
  unsigned char request_dump_;

  DISALLOW_COPY_AND_ASSIGN(SandboxedHandler);
};

}  // namespace
}  // namespace crashpad

namespace crash_reporter {
namespace {

#if defined(OS_ANDROID)

void SetJavaExceptionInfo(const char* info_string) {
  static crashpad::StringAnnotation<5 * 4096> exception_info("exception_info");
  if (info_string) {
    exception_info.Set(info_string);
  } else {
    exception_info.Clear();
  }
}

void SetBuildInfoAnnotations(std::map<std::string, std::string>* annotations) {
  base::android::BuildInfo* info = base::android::BuildInfo::GetInstance();

  (*annotations)["android_build_id"] = info->android_build_id();
  (*annotations)["android_build_fp"] = info->android_build_fp();
  (*annotations)["sdk"] = base::StringPrintf("%d", info->sdk_int());
  (*annotations)["device"] = info->device();
  (*annotations)["model"] = info->model();
  (*annotations)["brand"] = info->brand();
  (*annotations)["board"] = info->board();
  (*annotations)["installer_package_name"] = info->installer_package_name();
  (*annotations)["abi_name"] = info->abi_name();
  (*annotations)["custom_themes"] = info->custom_themes();
  (*annotations)["resources_verison"] = info->resources_version();
  (*annotations)["gms_core_version"] = info->gms_version_code();

  if (info->firebase_app_id()[0] != '\0') {
    (*annotations)["package"] = std::string(info->firebase_app_id()) + " v" +
                                info->package_version_code() + " (" +
                                info->package_version_name() + ")";
  }
}

#if defined(__arm__) && defined(__ARM_ARCH_7A__)
#define CURRENT_ABI "armeabi-v7a"
#elif defined(__arm__)
#define CURRENT_ABI "armeabi"
#elif defined(__i386__)
#define CURRENT_ABI "x86"
#elif defined(__mips__)
#define CURRENT_ABI "mips"
#elif defined(__x86_64__)
#define CURRENT_ABI "x86_64"
#elif defined(__aarch64__)
#define CURRENT_ABI "arm64-v8a"
#else
#error "Unsupported target abi"
#endif

void MakePackagePaths(std::string* classpath, std::string* libpath) {
  JNIEnv* env = base::android::AttachCurrentThread();

  base::android::ScopedJavaLocalRef<jstring> arch =
      base::android::ConvertUTF8ToJavaString(env,
                                             base::StringPiece(CURRENT_ABI));
  base::android::ScopedJavaLocalRef<jobjectArray> paths =
      Java_PackagePaths_makePackagePaths(env, arch);

  base::android::ConvertJavaStringToUTF8(
      env, static_cast<jstring>(env->GetObjectArrayElement(paths.obj(), 0)),
      classpath);
  base::android::ConvertJavaStringToUTF8(
      env, static_cast<jstring>(env->GetObjectArrayElement(paths.obj(), 1)),
      libpath);
}

// Copies and extends the current environment with CLASSPATH and LD_LIBRARY_PATH
// set to library paths in the APK.
bool BuildEnvironmentWithApk(std::vector<std::string>* result) {
  DCHECK(result->empty());

  std::string classpath;
  std::string library_path;
  MakePackagePaths(&classpath, &library_path);

  std::unique_ptr<base::Environment> env(base::Environment::Create());
  static constexpr char kClasspathVar[] = "CLASSPATH";
  std::string current_classpath;
  env->GetVar(kClasspathVar, &current_classpath);
  classpath += ":" + current_classpath;

  static constexpr char kLdLibraryPathVar[] = "LD_LIBRARY_PATH";
  std::string current_library_path;
  env->GetVar(kLdLibraryPathVar, &current_library_path);
  library_path += ":" + current_library_path;

  result->push_back("CLASSPATH=" + classpath);
  result->push_back("LD_LIBRARY_PATH=" + library_path);
  for (char** envp = environ; *envp != nullptr; ++envp) {
    if ((strncmp(*envp, kClasspathVar, strlen(kClasspathVar)) == 0 &&
         (*envp)[strlen(kClasspathVar)] == '=') ||
        (strncmp(*envp, kLdLibraryPathVar, strlen(kLdLibraryPathVar)) == 0 &&
         (*envp)[strlen(kLdLibraryPathVar)] == '=')) {
      continue;
    }
    result->push_back(*envp);
  }

  return true;
}

const char kCrashpadJavaMain[] =
    "org.chromium.components.crash.browser.CrashpadMain";

#endif  // OS_ANDROID

void BuildHandlerArgs(CrashReporterClient* crash_reporter_client,
                      base::FilePath* database_path,
                      base::FilePath* metrics_path,
                      std::string* url,
                      std::map<std::string, std::string>* process_annotations,
                      std::vector<std::string>* arguments) {
  crash_reporter_client->GetCrashDumpLocation(database_path);
  crash_reporter_client->GetCrashMetricsLocation(metrics_path);

// TODO(jperaza): Set URL for Android when Crashpad takes over report upload.
#if defined(GOOGLE_CHROME_BUILD) && defined(OFFICIAL_BUILD) && \
    !defined(OS_ANDROID)
  *url = "https://clients2.google.com/cr/report";
#else
  *url = std::string();
#endif

  std::string product_name;
  std::string product_version;
  std::string channel;
  crash_reporter_client->GetProductNameAndVersion(&product_name,
                                                  &product_version, &channel);
  (*process_annotations)["prod"] = product_name;
  (*process_annotations)["ver"] = product_version;

#if defined(OS_ANDROID)
  SetBuildInfoAnnotations(process_annotations);
#endif  // OS_ANDROID

#if defined(GOOGLE_CHROME_BUILD)
  // Empty means stable.
  const bool allow_empty_channel = true;
#else
  const bool allow_empty_channel = false;
#endif
  if (allow_empty_channel || !channel.empty()) {
    (*process_annotations)["channel"] = channel;
  }

#if defined(OS_ANDROID)
  (*process_annotations)["plat"] = std::string("Android");
#else
  (*process_annotations)["plat"] = std::string("Linux");
#endif

  if (crash_reporter_client->ShouldMonitorCrashHandlerExpensively()) {
    arguments->push_back("--monitor-self");
  }

  // Set up --monitor-self-annotation even in the absence of --monitor-self
  // so that minidumps produced by Crashpad's generate_dump tool will
  // contain these annotations.
  arguments->push_back("--monitor-self-annotation=ptype=crashpad-handler");
}

bool GetHandlerPath(base::FilePath* exe_dir, base::FilePath* handler_path) {
#if defined(OS_ANDROID)
  // There is not any normal way to package native executables in an Android
  // APK. The Crashpad handler is packaged like a loadable module, which
  // Android's APK installer expects to be named like a shared library, but it
  // is in fact a standalone executable.
  if (!base::PathService::Get(base::DIR_MODULE, exe_dir)) {
    return false;
  }
  *handler_path = exe_dir->Append("libcrashpad_handler.so");
#else
  if (!base::PathService::Get(base::DIR_EXE, exe_dir)) {
    return false;
  }
  *handler_path = exe_dir->Append("crashpad_handler");
#endif
  return true;
}

bool SetLdLibraryPath(const base::FilePath& lib_path) {
#if defined(OS_ANDROID) && defined(COMPONENT_BUILD)
  std::string library_path(lib_path.value());

  static constexpr char kLibraryPathVar[] = "LD_LIBRARY_PATH";
  std::unique_ptr<base::Environment> env(base::Environment::Create());
  std::string old_path;
  if (env->GetVar(kLibraryPathVar, &old_path)) {
    library_path.push_back(':');
    library_path.append(old_path);
  }

  if (!env->SetVar(kLibraryPathVar, library_path)) {
    return false;
  }
#endif

  return true;
}

class HandlerStarter {
 public:
  static HandlerStarter* Get() {
    static HandlerStarter* instance = new HandlerStarter();
    return instance;
  }

  base::FilePath Initialize(bool dump_at_crash) {
    base::FilePath database_path;
    base::FilePath metrics_path;
    std::string url;
    std::map<std::string, std::string> process_annotations;
    std::vector<std::string> arguments;
    BuildHandlerArgs(GetCrashReporterClient(), &database_path, &metrics_path,
                     &url, &process_annotations, &arguments);

    base::FilePath exe_dir;
    base::FilePath handler_path;
    if (!GetHandlerPath(&exe_dir, &handler_path)) {
      return database_path;
    }

    if (crashpad::SetSanitizationInfo(GetCrashReporterClient(),
                                      &browser_sanitization_info_)) {
      arguments.push_back(base::StringPrintf("--sanitization-information=%p",
                                             &browser_sanitization_info_));
    }

#if defined(OS_ANDROID)
    if (!base::PathExists(handler_path)) {
      use_java_handler_ = true;
    }

    if (!dump_at_crash) {
      return database_path;
    }

    if (use_java_handler_) {
      std::vector<std::string> env;
      if (!BuildEnvironmentWithApk(&env)) {
        return database_path;
      }

      // TODO(jperaza): The logic for constructing an appropriate
      // CLASSPATH/LD_LIBRARY_PATH won't work for Android Q+. The handler will
      // need to be launched by executing the dynamic linker instead.
      bool result = GetCrashpadClient().StartJavaHandlerAtCrash(
          kCrashpadJavaMain, &env, database_path, metrics_path, url,
          process_annotations, arguments);
      DCHECK(result);
      return database_path;
    }
#endif

    if (!SetLdLibraryPath(exe_dir)) {
      return database_path;
    }

    bool result = GetCrashpadClient().StartHandlerAtCrash(
        handler_path, database_path, metrics_path, url, process_annotations,
        arguments);
    DCHECK(result);
    return database_path;
  }

  bool StartHandlerForClient(CrashReporterClient* client, int fd) {
    base::FilePath database_path;
    base::FilePath metrics_path;
    std::string url;
    std::map<std::string, std::string> process_annotations;
    std::vector<std::string> arguments;
    BuildHandlerArgs(client, &database_path, &metrics_path, &url,
                     &process_annotations, &arguments);

#if defined(OS_ANDROID)
    std::string browser_ptype;
    if (GetCrashReporterClient()->GetBrowserProcessType(&browser_ptype)) {
      process_annotations["ptype"] = browser_ptype;
    }
#endif  // defined(OS_ANDROID)

    base::FilePath exe_dir;
    base::FilePath handler_path;
    if (!GetHandlerPath(&exe_dir, &handler_path)) {
      return false;
    }

#if defined(OS_ANDROID)
    if (use_java_handler_) {
      std::vector<std::string> env;
      if (!BuildEnvironmentWithApk(&env)) {
        return false;
      }

      // TODO(jperaza): The logic for constructing an appropriate
      // CLASSPATH/LD_LIBRARY_PATH won't work for Android Q+. The handler will
      // need to be launched by executing the dynamic linker instead.
      bool result = GetCrashpadClient().StartJavaHandlerForClient(
          kCrashpadJavaMain, &env, database_path, metrics_path, url,
          process_annotations, arguments, fd);
      return result;
    }
#endif

    if (!SetLdLibraryPath(exe_dir)) {
      return false;
    }

    return GetCrashpadClient().StartHandlerForClient(
        handler_path, database_path, metrics_path, url, process_annotations,
        arguments, fd);
  }

 private:
  HandlerStarter() = default;
  ~HandlerStarter() = delete;

  crashpad::SanitizationInformation browser_sanitization_info_;
#if defined(OS_ANDROID)
  bool use_java_handler_ = false;
#endif

  DISALLOW_COPY_AND_ASSIGN(HandlerStarter);
};

bool ConnectToHandler(CrashReporterClient* client, base::ScopedFD* connection) {
  int fds[2];
  if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) != 0) {
    PLOG(ERROR) << "socketpair";
    return false;
  }
  base::ScopedFD local_connection(fds[0]);
  base::ScopedFD handlers_socket(fds[1]);

  if (!HandlerStarter::Get()->StartHandlerForClient(client,
                                                    handlers_socket.get())) {
    return false;
  }

  *connection = std::move(local_connection);
  return true;
}

bool g_is_browser = false;

}  // namespace

#if defined(OS_ANDROID)
// TODO(jperaza): This might be simplified to have both the browser and child
// processes use CRASHPAD_SIMULATE_CRASH() if CrashpadClient allows injecting
// the Chromium specific SandboxedHandler.
void DumpWithoutCrashing() {
  if (g_is_browser) {
    CRASHPAD_SIMULATE_CRASH();
  } else {
    siginfo_t siginfo;
    siginfo.si_signo = crashpad::Signals::kSimulatedSigno;
    siginfo.si_errno = 0;
    siginfo.si_code = 0;

    ucontext_t context;
    crashpad::CaptureContext(&context);

    crashpad::SandboxedHandler::Get()->HandleCrashNonFatal(siginfo.si_signo,
                                                           &siginfo, &context);
  }
}
#endif

bool DumpWithoutCrashingForClient(CrashReporterClient* client) {
  base::ScopedFD connection;
  if (!ConnectToHandler(client, &connection)) {
    return false;
  }

  siginfo_t siginfo;
  siginfo.si_signo = crashpad::Signals::kSimulatedSigno;
  siginfo.si_errno = 0;
  siginfo.si_code = 0;

  ucontext_t context;
  crashpad::CaptureContext(&context);

  crashpad::SanitizationInformation sanitization;
  crashpad::SetSanitizationInfo(client, &sanitization);

  crashpad::ExceptionInformation exception;
  crashpad::SetExceptionInformation(&siginfo, &context, &exception);

  crashpad::ClientInformation info;
  crashpad::SetClientInformation(&exception, &sanitization, &info);

  crashpad::ScopedPrSetDumpable set_dumpable(/* may_log= */ false);

  crashpad::ExceptionHandlerClient handler_client(connection.get());
  return handler_client.RequestCrashDump(info) == 0;
}

namespace internal {

bool StartHandlerForClient(int fd) {
  return HandlerStarter::Get()->StartHandlerForClient(GetCrashReporterClient(),
                                                      fd);
}

base::FilePath PlatformCrashpadInitialization(
    bool initial_client,
    bool browser_process,
    bool embedded_handler,
    const std::string& user_data_dir,
    const base::FilePath& exe_path,
    const std::vector<std::string>& initial_arguments) {
  DCHECK_EQ(initial_client, browser_process);
  DCHECK(initial_arguments.empty());

  // Not used on Linux/Android.
  DCHECK(!embedded_handler);
  DCHECK(exe_path.empty());

  g_is_browser = browser_process;

  bool dump_at_crash = true;
#if defined(OS_ANDROID)
  base::android::SetJavaExceptionCallback(SetJavaExceptionInfo);

  unsigned int dump_percentage =
      GetCrashReporterClient()->GetCrashDumpPercentageForWebView();
  if (dump_percentage < 100 && rand() % 100 >= dump_percentage) {
    dump_at_crash = false;
  }
#endif  // OS_ANDROID

  if (browser_process) {
    HandlerStarter* starter = HandlerStarter::Get();
    return starter->Initialize(dump_at_crash);
  }

  crashpad::SandboxedHandler* handler = crashpad::SandboxedHandler::Get();
  bool result = handler->Initialize(dump_at_crash);
  DCHECK(result);

  return base::FilePath();
}

}  // namespace internal

}  // namespace crash_reporter
