// 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/check_op.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
