// 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 "client/simulate_crash.h"

#include <mach/mach.h>
#include <string.h>
#include <sys/types.h>

#include "base/macros.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/mac/mach_errors.h"
#include "test/mac/mach_multiprocess.h"
#include "util/mach/exc_server_variants.h"
#include "util/mach/exception_behaviors.h"
#include "util/mach/exception_ports.h"
#include "util/mach/mach_extensions.h"
#include "util/mach/mach_message.h"
#include "util/mach/mach_message_server.h"
#include "util/mach/symbolic_constants_mach.h"
#include "util/misc/implicit_cast.h"

namespace crashpad {
namespace test {
namespace {

class TestSimulateCrashMac final : public MachMultiprocess,
                                   public UniversalMachExcServer::Interface {
 public:
  // Defines which targets the child should set an EXC_CRASH exception handler
  // for.
  enum ExceptionPortsTarget {
    // The child should clear its EXC_CRASH handler for both its task and thread
    // targets. SimulateCrash() will attempt to deliver the exception to the
    // host target, which will fail if not running as root. In any case, the
    // parent should not expect to receive any exception message from the child.
    kExceptionPortsTargetNone = 0,

    // The child will set an EXC_CRASH handler for its task target, and clear it
    // for its thread target. The parent runs an exception server to receive
    // the child’s simulated crash message.
    kExceptionPortsTargetTask,

    // The child will set an EXC_CRASH handler for its thread target, and clear
    // it for its task target. The parent runs an exception server to receive
    // the child’s simulated crash message.
    kExceptionPortsTargetThread,

    // The child sets an EXC_CRASH handler for both its task and thread targets.
    // The parent runs an exception server to receive the message expected to be
    // delivered to the thread target, but returns an error code. The child will
    // then fall back to trying the server registered for the task target,
    // sending a second message to the parent. The server in the parent will
    // handle this one successfully.
    kExceptionPortsTargetBoth,
  };

  TestSimulateCrashMac(ExceptionPortsTarget target,
                       exception_behavior_t behavior,
                       thread_state_flavor_t flavor)
      : MachMultiprocess(),
        UniversalMachExcServer::Interface(),
        target_(target),
        behavior_(behavior),
        flavor_(flavor),
        succeed_(true) {
  }

  ~TestSimulateCrashMac() {}

  // 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;

    // Check the entire exception message, because most or all of it was
    // generated by SimulateCrash() instead of the kernel.

    EXPECT_EQ(behavior, behavior_);
    EXPECT_EQ(exception_port, LocalPort());
    if (ExceptionBehaviorHasIdentity(behavior)) {
      EXPECT_NE(thread, THREAD_NULL);
      EXPECT_EQ(task, ChildTask());
    } else {
      EXPECT_EQ(thread, THREAD_NULL);
      EXPECT_EQ(task, TASK_NULL);
    }
    EXPECT_EQ(exception, kMachExceptionSimulated);
    EXPECT_EQ(code_count, 2u);
    if (code_count >= 1) {
      EXPECT_EQ(code[0], 0);
    }
    if (code_count >= 2) {
      EXPECT_EQ(code[1], 0);
    }
    if (!ExceptionBehaviorHasState(behavior)) {
      EXPECT_EQ(*flavor, THREAD_STATE_NONE);
    } else {
      EXPECT_EQ(*flavor, flavor_);
      switch (*flavor) {
#if defined(ARCH_CPU_X86_FAMILY)
        case x86_THREAD_STATE: {
          EXPECT_EQ(old_state_count, x86_THREAD_STATE_COUNT);
          const x86_thread_state* state =
              reinterpret_cast<const x86_thread_state*>(old_state);
          switch (state->tsh.flavor) {
            case x86_THREAD_STATE32:
              EXPECT_EQ(implicit_cast<uint32_t>(state->tsh.count),
                        implicit_cast<uint32_t>(x86_THREAD_STATE32_COUNT));
              break;
            case x86_THREAD_STATE64:
              EXPECT_EQ(implicit_cast<uint32_t>(state->tsh.count),
                        implicit_cast<uint32_t>(x86_THREAD_STATE64_COUNT));
              break;
            default:
              ADD_FAILURE() << "unexpected tsh.flavor " << state->tsh.flavor;
              break;
          }
          break;
        }
        case x86_FLOAT_STATE: {
          EXPECT_EQ(old_state_count, x86_FLOAT_STATE_COUNT);
          const x86_float_state* state =
              reinterpret_cast<const x86_float_state*>(old_state);
          switch (state->fsh.flavor) {
            case x86_FLOAT_STATE32:
              EXPECT_EQ(implicit_cast<uint32_t>(state->fsh.count),
                        implicit_cast<uint32_t>(x86_FLOAT_STATE32_COUNT));
              break;
            case x86_FLOAT_STATE64:
              EXPECT_EQ(implicit_cast<uint32_t>(state->fsh.count),
                        implicit_cast<uint32_t>(x86_FLOAT_STATE64_COUNT));
              break;
            default:
              ADD_FAILURE() << "unexpected fsh.flavor " << state->fsh.flavor;
              break;
          }
          break;
        }
        case x86_DEBUG_STATE: {
          EXPECT_EQ(old_state_count, x86_DEBUG_STATE_COUNT);
          const x86_debug_state* state =
              reinterpret_cast<const x86_debug_state*>(old_state);
          switch (state->dsh.flavor) {
            case x86_DEBUG_STATE32:
              EXPECT_EQ(implicit_cast<uint32_t>(state->dsh.count),
                        implicit_cast<uint32_t>(x86_DEBUG_STATE32_COUNT));
              break;
            case x86_DEBUG_STATE64:
              EXPECT_EQ(implicit_cast<uint32_t>(state->dsh.count),
                        implicit_cast<uint32_t>(x86_DEBUG_STATE64_COUNT));
              break;
            default:
              ADD_FAILURE() << "unexpected dsh.flavor " << state->dsh.flavor;
              break;
          }
          break;
        }
        case x86_THREAD_STATE32:
          EXPECT_EQ(old_state_count, x86_THREAD_STATE32_COUNT);
          break;
        case x86_FLOAT_STATE32:
          EXPECT_EQ(old_state_count, x86_FLOAT_STATE32_COUNT);
          break;
        case x86_DEBUG_STATE32:
          EXPECT_EQ(old_state_count, x86_DEBUG_STATE32_COUNT);
          break;
        case x86_THREAD_STATE64:
          EXPECT_EQ(old_state_count, x86_THREAD_STATE64_COUNT);
          break;
        case x86_FLOAT_STATE64:
          EXPECT_EQ(old_state_count, x86_FLOAT_STATE64_COUNT);
          break;
        case x86_DEBUG_STATE64:
          EXPECT_EQ(old_state_count, x86_DEBUG_STATE64_COUNT);
          break;
#else
#error Port to your CPU architecture
#endif
        default:
          ADD_FAILURE() << "unexpected flavor " << *flavor;
          break;
      }

      // Attempt to set a garbage thread state, which would cause the child to
      // crash inside SimulateCrash() if it actually succeeded. This tests that
      // SimulateCrash() ignores new_state instead of attempting to set the
      // state as the kernel would do. This operates in conjunction with the
      // |true| argument to ExcServerSuccessfulReturnValue() below.
      *new_state_count = old_state_count;
      size_t new_state_size = sizeof(natural_t) * old_state_count;
      memset(new_state, 0xa5, new_state_size);
    }

    if (!succeed_) {
      // The client has registered EXC_CRASH handlers for both its thread and
      // task targets, and sent a simulated exception message to its
      // thread-level EXC_CRASH handler. To test that it will fall back to
      // trying the task-level EXC_CRASH handler, return a failure code, which
      // should cause SimulateCrash() to try the next target.
      EXPECT_EQ(target_, kExceptionPortsTargetBoth);
      return KERN_ABORTED;
    }

    ExcServerCopyState(
        behavior, old_state, old_state_count, new_state, new_state_count);

    return ExcServerSuccessfulReturnValue(exception, behavior, true);
  }

 private:
  // MachMultiprocess:

  void MachMultiprocessParent() override {
    if (target_ == kExceptionPortsTargetNone) {
      // The child does not have any EXC_CRASH handlers registered for its
      // thread or task targets, so no exception message is expected to be
      // generated. Don’t run the server at all.
      return;
    }

    UniversalMachExcServer universal_mach_exc_server(this);

    mach_msg_return_t mr;
    if (target_ == kExceptionPortsTargetBoth) {
      // The client has registered EXC_CRASH handlers for both its thread and
      // task targets. Run a server that will return a failure code when the
      // exception message is sent to the thread target, which will cause the
      // client to fall back to the task target and send another message.
      succeed_ = false;
      mr = MachMessageServer::Run(&universal_mach_exc_server,
                                  LocalPort(),
                                  MACH_MSG_OPTION_NONE,
                                  MachMessageServer::kOneShot,
                                  MachMessageServer::kReceiveLargeError,
                                  kMachMessageTimeoutWaitIndefinitely);
      EXPECT_EQ(mr, MACH_MSG_SUCCESS)
          << MachErrorMessage(mr, "MachMessageServer::Run");
    }

    succeed_ = true;
    mr = MachMessageServer::Run(&universal_mach_exc_server,
                                LocalPort(),
                                MACH_MSG_OPTION_NONE,
                                MachMessageServer::kOneShot,
                                MachMessageServer::kReceiveLargeError,
                                kMachMessageTimeoutWaitIndefinitely);
    EXPECT_EQ(mr, MACH_MSG_SUCCESS)
        << MachErrorMessage(mr, "MachMessageServer::Run");
  }

  void MachMultiprocessChild() override {
    bool task_valid = target_ == kExceptionPortsTargetTask ||
                      target_ == kExceptionPortsTargetBoth;
    ExceptionPorts task_exception_ports(ExceptionPorts::kTargetTypeTask,
                                        TASK_NULL);
    ASSERT_TRUE(task_exception_ports.SetExceptionPort(
        EXC_MASK_CRASH,
        task_valid ? RemotePort() : MACH_PORT_NULL,
        behavior_,
        flavor_));

    bool thread_valid = target_ == kExceptionPortsTargetThread ||
                        target_ == kExceptionPortsTargetBoth;
    ExceptionPorts thread_exception_ports(ExceptionPorts::kTargetTypeThread,
                                          THREAD_NULL);
    ASSERT_TRUE(thread_exception_ports.SetExceptionPort(
        EXC_MASK_CRASH,
        thread_valid ? RemotePort() : MACH_PORT_NULL,
        behavior_,
        flavor_));

    CRASHPAD_SIMULATE_CRASH();
  }

  ExceptionPortsTarget target_;
  exception_behavior_t behavior_;
  thread_state_flavor_t flavor_;
  bool succeed_;

  DISALLOW_COPY_AND_ASSIGN(TestSimulateCrashMac);
};

TEST(SimulateCrash, SimulateCrash) {
  static constexpr TestSimulateCrashMac::ExceptionPortsTarget kTargets[] = {
      TestSimulateCrashMac::kExceptionPortsTargetNone,
      TestSimulateCrashMac::kExceptionPortsTargetTask,
      TestSimulateCrashMac::kExceptionPortsTargetThread,
      TestSimulateCrashMac::kExceptionPortsTargetBoth,
  };

  static constexpr exception_behavior_t kBehaviors[] = {
      EXCEPTION_DEFAULT,
      EXCEPTION_STATE,
      EXCEPTION_STATE_IDENTITY,
      EXCEPTION_DEFAULT | kMachExceptionCodes,
      EXCEPTION_STATE | kMachExceptionCodes,
      EXCEPTION_STATE_IDENTITY | kMachExceptionCodes,
  };

  static constexpr thread_state_flavor_t kFlavors[] = {
#if defined(ARCH_CPU_X86_FAMILY)
      x86_THREAD_STATE,
      x86_FLOAT_STATE,
      x86_DEBUG_STATE,
#if defined(ARCH_CPU_X86)
      x86_THREAD_STATE32,
      x86_FLOAT_STATE32,
      x86_DEBUG_STATE32,
#elif defined(ARCH_CPU_X86_64)
      x86_THREAD_STATE64,
      x86_FLOAT_STATE64,
      x86_DEBUG_STATE64,
#endif
#else
#error Port to your CPU architecture
#endif
  };

  for (size_t target_index = 0; target_index < base::size(kTargets);
       ++target_index) {
    TestSimulateCrashMac::ExceptionPortsTarget target = kTargets[target_index];
    SCOPED_TRACE(base::StringPrintf(
        "target_index %zu, target %d", target_index, target));

    for (size_t behavior_index = 0; behavior_index < base::size(kBehaviors);
         ++behavior_index) {
      exception_behavior_t behavior = kBehaviors[behavior_index];
      SCOPED_TRACE(base::StringPrintf(
          "behavior_index %zu, behavior %s",
          behavior_index,
          ExceptionBehaviorToString(behavior, kUseFullName | kUnknownIsNumeric)
              .c_str()));

      if (!ExceptionBehaviorHasState(behavior)) {
        TestSimulateCrashMac test_simulate_crash_mac(
            target, behavior, THREAD_STATE_NONE);
        test_simulate_crash_mac.Run();
      } else {
        for (size_t flavor_index = 0; flavor_index < base::size(kFlavors);
             ++flavor_index) {
          thread_state_flavor_t flavor = kFlavors[flavor_index];
          SCOPED_TRACE(base::StringPrintf(
              "flavor_index %zu, flavor %s",
              flavor_index,
              ThreadStateFlavorToString(
                  flavor, kUseFullName | kUnknownIsNumeric).c_str()));

          TestSimulateCrashMac test_simulate_crash_mac(
              target, behavior, flavor);
          test_simulate_crash_mac.Run();
        }
      }
    }
  }
}

}  // namespace
}  // namespace test
}  // namespace crashpad
