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

#include <errno.h>
#include <stdlib.h>
#include <unistd.h>

#include <string>

#include "base/logging.h"
#include "base/mac/scoped_mach_port.h"
#include "base/strings/stringprintf.h"
#include "handler/mac/exception_handler_server.h"
#include "util/mach/bootstrap.h"
#include "util/mach/exc_server_variants.h"
#include "util/mach/exception_ports.h"
#include "util/mach/mach_extensions.h"
#include "util/misc/random_string.h"
#include "util/thread/thread.h"

namespace crashpad {
namespace test {

namespace {

constexpr char kServiceEnvironmentVariable[] =
    "CRASHPAD_EXCEPTION_SWALLOWER_SERVICE";

ExceptionSwallower* g_exception_swallower;

// Like getenv(), but fails a CHECK() if the underlying function fails. It’s not
// considered a failure for |name| to be unset in the environment. In that case,
// nullptr is returned.
const char* CheckedGetenv(const char* name) {
  errno = 0;
  const char* value;
  PCHECK((value = getenv(name)) || errno == 0) << "getenv";
  return value;
}

}  // namespace

class ExceptionSwallower::ExceptionSwallowerThread
    : public Thread,
      public UniversalMachExcServer::Interface {
 public:
  explicit ExceptionSwallowerThread(
      base::mac::ScopedMachReceiveRight receive_right)
      : Thread(),
        UniversalMachExcServer::Interface(),
        exception_handler_server_(std::move(receive_right), true),
        pid_(getpid()) {
    Start();
  }

  ~ExceptionSwallowerThread() override {}

  void Stop() { exception_handler_server_.Stop(); }

  // Returns the process ID that the thread is running in. This is used to
  // detect misuses that place the exception swallower server thread and code
  // that wants its exceptions swallowed in the same process.
  pid_t ProcessID() const { return pid_; }

 private:
  // Thread:

  void ThreadMain() override { exception_handler_server_.Run(this); }

  // UniversalMachExcServer::Interface:

  kern_return_t CatchMachException(exception_behavior_t behavior,
                                   exception_handler_t exception_port,
                                   thread_t thread,
                                   task_t task,
                                   exception_type_t exception,
                                   const mach_exception_data_type_t* code,
                                   mach_msg_type_number_t code_count,
                                   thread_state_flavor_t* flavor,
                                   ConstThreadState old_state,
                                   mach_msg_type_number_t old_state_count,
                                   thread_state_t new_state,
                                   mach_msg_type_number_t* new_state_count,
                                   const mach_msg_trailer_t* trailer,
                                   bool* destroy_complex_request) override {
    *destroy_complex_request = true;

    // Swallow.

    ExcServerCopyState(
        behavior, old_state, old_state_count, new_state, new_state_count);
    return ExcServerSuccessfulReturnValue(exception, behavior, false);
  }

  ExceptionHandlerServer exception_handler_server_;
  pid_t pid_;

  DISALLOW_COPY_AND_ASSIGN(ExceptionSwallowerThread);
};

ExceptionSwallower::ExceptionSwallower() : exception_swallower_thread_() {
  CHECK(!g_exception_swallower);
  g_exception_swallower = this;

  if (CheckedGetenv(kServiceEnvironmentVariable)) {
    // The environment variable is already set, so just proceed with the
    // existing service. This normally happens when the Google Test “threadsafe”
    // death test style is chosen, because the test child process will
    // re-execute code already run in the test parent process. See
    // https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#death-test-styles.
    return;
  }

  std::string service_name =
      base::StringPrintf("org.chromium.crashpad.test.exception_swallower.%d.%s",
                         getpid(),
                         RandomString().c_str());
  base::mac::ScopedMachReceiveRight receive_right(
      BootstrapCheckIn(service_name));
  CHECK(receive_right.is_valid());

  exception_swallower_thread_.reset(
      new ExceptionSwallowerThread(std::move(receive_right)));

  PCHECK(setenv(kServiceEnvironmentVariable, service_name.c_str(), 1) == 0)
      << "setenv";
}

ExceptionSwallower::~ExceptionSwallower() {
  PCHECK(unsetenv(kServiceEnvironmentVariable) == 0) << "unsetenv";

  exception_swallower_thread_->Stop();
  exception_swallower_thread_->Join();

  CHECK_EQ(g_exception_swallower, this);
  g_exception_swallower = nullptr;
}

// static
void ExceptionSwallower::SwallowExceptions() {
  // The exception swallower thread can’t be in this process, because the
  // EXC_CRASH or EXC_CORPSE_NOTIFY exceptions that it needs to swallow will be
  // delivered after a crash has occurred and none of its threads will be
  // scheduled to run.
  CHECK(!g_exception_swallower ||
        !g_exception_swallower->exception_swallower_thread_ ||
        g_exception_swallower->exception_swallower_thread_->ProcessID() !=
            getpid());

  const char* service_name = CheckedGetenv(kServiceEnvironmentVariable);
  CHECK(service_name);

  base::mac::ScopedMachSendRight exception_swallower_port(
      BootstrapLookUp(service_name));
  CHECK(exception_swallower_port.is_valid());

  ExceptionPorts task_exception_ports(ExceptionPorts::kTargetTypeTask,
                                      TASK_NULL);

  // The mask is similar to the one used by CrashpadClient::UseHandler(), but
  // EXC_CORPSE_NOTIFY is added. This is done for the benefit of tests that
  // crash intentionally with their own custom exception port set for EXC_CRASH.
  // In that case, depending on the actions taken by the EXC_CRASH handler, the
  // exception may be transformed by the kernel into an EXC_CORPSE_NOTIFY, which
  // would be sent to an EXC_CORPSE_NOTIFY handler, normally the system’s crash
  // reporter at the task or host level. See 10.13.0
  // xnu-4570.1.46/bsd/kern/kern_exit.c proc_prepareexit(). Swallowing
  // EXC_CORPSE_NOTIFY at the task level prevents such exceptions from reaching
  // the system’s crash reporter.
  CHECK(task_exception_ports.SetExceptionPort(
      (EXC_MASK_CRASH |
       EXC_MASK_RESOURCE |
       EXC_MASK_GUARD |
       EXC_MASK_CORPSE_NOTIFY) & ExcMaskValid(),
      exception_swallower_port.get(),
      EXCEPTION_DEFAULT,
      THREAD_STATE_NONE));
}

}  // namespace test
}  // namespace crashpad
