// Copyright 2013 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// exploitability_linux.cc: Linux specific exploitability engine.
//
// Provides a guess at the exploitability of the crash for the Linux
// platform given a minidump and process_state.
//
// Author: Matthew Riley

#ifdef HAVE_CONFIG_H
#include <config.h>  // Must come first
#endif

#include "processor/exploitability_linux.h"

#include <string.h>

#include <string>

#include "google_breakpad/common/minidump_exception_linux.h"
#include "google_breakpad/processor/call_stack.h"
#include "google_breakpad/processor/process_state.h"
#include "google_breakpad/processor/stack_frame.h"
#ifdef __linux__
#include "processor/disassembler_objdump.h"
#endif
#include "processor/logging.h"

namespace {

// Prefixes for memory mapping names.
constexpr char kHeapPrefix[] = "[heap";
constexpr char kStackPrefix[] =  "[stack";

// This function in libc is called if the program was compiled with
// -fstack-protector and a function's stack canary changes.
constexpr char kStackCheckFailureFunction[] = "__stack_chk_fail";

// This function in libc is called if the program was compiled with
// -D_FORTIFY_SOURCE=2, a function like strcpy() is called, and the runtime
// can determine that the call would overflow the target buffer.
constexpr char kBoundsCheckFailureFunction[] = "__chk_fail";

}  // namespace

namespace google_breakpad {

ExploitabilityLinux::ExploitabilityLinux(Minidump* dump,
                                         ProcessState* process_state)
    : Exploitability(dump, process_state),
      enable_objdump_(false) { }

ExploitabilityLinux::ExploitabilityLinux(Minidump* dump,
                                         ProcessState* process_state,
                                         bool enable_objdump)
    : Exploitability(dump, process_state),
      enable_objdump_(enable_objdump) { }


ExploitabilityRating ExploitabilityLinux::CheckPlatformExploitability() {
  // Check the crashing thread for functions suggesting a buffer overflow or
  // stack smash.
  if (process_state_->requesting_thread() != -1) {
    CallStack* crashing_thread =
        process_state_->threads()->at(process_state_->requesting_thread());
    const vector<StackFrame*>& crashing_thread_frames =
        *crashing_thread->frames();
    for (size_t i = 0; i < crashing_thread_frames.size(); ++i) {
      if (crashing_thread_frames[i]->function_name ==
          kStackCheckFailureFunction) {
        return EXPLOITABILITY_HIGH;
      }

      if (crashing_thread_frames[i]->function_name ==
          kBoundsCheckFailureFunction) {
        return EXPLOITABILITY_HIGH;
      }
    }
  }

  // Getting exception data. (It should exist for all minidumps.)
  MinidumpException* exception = dump_->GetException();
  if (exception == nullptr) {
    BPLOG(INFO) << "No exception record.";
    return EXPLOITABILITY_ERR_PROCESSING;
  }
  const MDRawExceptionStream* raw_exception_stream = exception->exception();
  if (raw_exception_stream == nullptr) {
    BPLOG(INFO) << "No raw exception stream.";
    return EXPLOITABILITY_ERR_PROCESSING;
  }

  // Checking for benign exceptions that caused the crash.
  if (this->BenignCrashTrigger(raw_exception_stream)) {
    return EXPLOITABILITY_NONE;
  }

  // Check if the instruction pointer is in a valid instruction region
  // by finding if it maps to an executable part of memory.
  uint64_t instruction_ptr = 0;
  uint64_t stack_ptr = 0;

  const MinidumpContext* context = exception->GetContext();
  if (context == nullptr) {
    BPLOG(INFO) << "No exception context.";
    return EXPLOITABILITY_ERR_PROCESSING;
  }

  // Getting the instruction pointer.
  if (!context->GetInstructionPointer(&instruction_ptr)) {
    BPLOG(INFO) << "Failed to retrieve instruction pointer.";
    return EXPLOITABILITY_ERR_PROCESSING;
  }

  // Getting the stack pointer.
  if (!context->GetStackPointer(&stack_ptr)) {
    BPLOG(INFO) << "Failed to retrieve stack pointer.";
    return EXPLOITABILITY_ERR_PROCESSING;
  }

  // Checking for the instruction pointer in a valid instruction region,
  // a misplaced stack pointer, and an executable stack or heap.
  if (!this->InstructionPointerInCode(instruction_ptr) ||
       this->StackPointerOffStack(stack_ptr) ||
       this->ExecutableStackOrHeap()) {
    return EXPLOITABILITY_HIGH;
  }

  // Check for write to read only memory or invalid memory, shelling out
  // to objdump is enabled.
  if (enable_objdump_ && this->EndedOnIllegalWrite(instruction_ptr)) {
    return EXPLOITABILITY_HIGH;
  }

  // There was no strong evidence suggesting exploitability, but the minidump
  // does not appear totally benign either.
  return EXPLOITABILITY_INTERESTING;
}

bool ExploitabilityLinux::EndedOnIllegalWrite(uint64_t instruction_ptr) {
#ifndef __linux__
  BPLOG(INFO) << "MinGW does not support fork and exec. Terminating method.";
  return false;
#else
  // Get memory region containing instruction pointer.
  MinidumpMemoryList* memory_list = dump_->GetMemoryList();
  MinidumpMemoryRegion* memory_region =
      memory_list ?
      memory_list->GetMemoryRegionForAddress(instruction_ptr) : nullptr;
  if (!memory_region) {
    BPLOG(INFO) << "No memory region around instruction pointer.";
    return false;
  }

  // Get exception data to find architecture.
  std::string architecture = "";
  MinidumpException* exception = dump_->GetException();
  // This should never evaluate to true, since this should not be reachable
  // without checking for exception data earlier.
  if (!exception) {
    BPLOG(INFO) << "No exception data.";
    return false;
  }
  const MDRawExceptionStream* raw_exception_stream = exception->exception();
  const MinidumpContext* context = exception->GetContext();
  // This should not evaluate to true, for the same reason mentioned above.
  if (!raw_exception_stream || !context) {
    BPLOG(INFO) << "No exception or architecture data.";
    return false;
  }

  DisassemblerObjdump disassembler(context->GetContextCPU(), memory_region,
                                   instruction_ptr);
  if (!disassembler.IsValid()) {
    BPLOG(INFO) << "Disassembling fault instruction failed.";
    return false;
  }

  // Check if the operation is a write to memory.
  // First, the instruction must one that can write to memory.
  auto instruction = disassembler.operation();
  if (!instruction.compare("mov") || !instruction.compare("inc") ||
      !instruction.compare("dec") || !instruction.compare("and") ||
      !instruction.compare("or") || !instruction.compare("xor") ||
      !instruction.compare("not") || !instruction.compare("neg") ||
      !instruction.compare("add") || !instruction.compare("sub") ||
      !instruction.compare("shl") || !instruction.compare("shr")) {
    uint64_t write_address = 0;

    // Check that the destination is a memory address. CalculateDestAddress will
    // return false if the destination is not a memory address.
    if (!disassembler.CalculateDestAddress(*context, write_address)) {
      return false;
    }

    // If the program crashed as a result of a write, the destination of
    // the write must have been an address that did not permit writing.
    // However, if the address is under 4k, due to program protections,
    // the crash does not suggest exploitability for writes with such a
    // low target address.
    return write_address > 4096;
  } else {
    return false;
  }
#endif  // __linux__
}

bool ExploitabilityLinux::StackPointerOffStack(uint64_t stack_ptr) {
  MinidumpLinuxMapsList* linux_maps_list = dump_->GetLinuxMapsList();
  // Inconclusive if there are no mappings available.
  if (!linux_maps_list) {
    return false;
  }
  const MinidumpLinuxMaps* linux_maps =
      linux_maps_list->GetLinuxMapsForAddress(stack_ptr);
  // Checks if the stack pointer maps to a valid mapping and if the mapping
  // is not the stack. If the mapping has no name, it is inconclusive whether
  // it is off the stack.
  return !linux_maps || (linux_maps->GetPathname().compare("") &&
                         linux_maps->GetPathname().compare(
                             0, strlen(kStackPrefix), kStackPrefix));
}

bool ExploitabilityLinux::ExecutableStackOrHeap() {
  MinidumpLinuxMapsList* linux_maps_list = dump_->GetLinuxMapsList();
  if (linux_maps_list) {
    for (size_t i = 0; i < linux_maps_list->get_maps_count(); i++) {
      const MinidumpLinuxMaps* linux_maps =
          linux_maps_list->GetLinuxMapsAtIndex(i);
      // Check for executable stack or heap for each mapping.
      if (linux_maps && (!linux_maps->GetPathname().compare(
                             0, strlen(kStackPrefix), kStackPrefix) ||
                         !linux_maps->GetPathname().compare(
                             0, strlen(kHeapPrefix), kHeapPrefix)) &&
          linux_maps->IsExecutable()) {
        return true;
      }
    }
  }
  return false;
}

bool ExploitabilityLinux::InstructionPointerInCode(uint64_t instruction_ptr) {
  // Get Linux memory mapping from /proc/self/maps. Checking whether the
  // region the instruction pointer is in has executable permission can tell
  // whether it is in a valid code region. If there is no mapping for the
  // instruction pointer, it is indicative that the instruction pointer is
  // not within a module, which implies that it is outside a valid area.
  MinidumpLinuxMapsList* linux_maps_list = dump_->GetLinuxMapsList();
  const MinidumpLinuxMaps* linux_maps =
      linux_maps_list ?
      linux_maps_list->GetLinuxMapsForAddress(instruction_ptr) : nullptr;
  return linux_maps ? linux_maps->IsExecutable() : false;
}

bool ExploitabilityLinux::BenignCrashTrigger(
    const MDRawExceptionStream* raw_exception_stream) {
  // Check the cause of crash.
  // If the exception of the crash is a benign exception,
  // it is probably not exploitable.
  switch (raw_exception_stream->exception_record.exception_code) {
    case MD_EXCEPTION_CODE_LIN_SIGHUP:
    case MD_EXCEPTION_CODE_LIN_SIGINT:
    case MD_EXCEPTION_CODE_LIN_SIGQUIT:
    case MD_EXCEPTION_CODE_LIN_SIGTRAP:
    case MD_EXCEPTION_CODE_LIN_SIGABRT:
    case MD_EXCEPTION_CODE_LIN_SIGFPE:
    case MD_EXCEPTION_CODE_LIN_SIGKILL:
    case MD_EXCEPTION_CODE_LIN_SIGUSR1:
    case MD_EXCEPTION_CODE_LIN_SIGUSR2:
    case MD_EXCEPTION_CODE_LIN_SIGPIPE:
    case MD_EXCEPTION_CODE_LIN_SIGALRM:
    case MD_EXCEPTION_CODE_LIN_SIGTERM:
    case MD_EXCEPTION_CODE_LIN_SIGCHLD:
    case MD_EXCEPTION_CODE_LIN_SIGCONT:
    case MD_EXCEPTION_CODE_LIN_SIGSTOP:
    case MD_EXCEPTION_CODE_LIN_SIGTSTP:
    case MD_EXCEPTION_CODE_LIN_SIGTTIN:
    case MD_EXCEPTION_CODE_LIN_SIGTTOU:
    case MD_EXCEPTION_CODE_LIN_SIGURG:
    case MD_EXCEPTION_CODE_LIN_SIGXCPU:
    case MD_EXCEPTION_CODE_LIN_SIGXFSZ:
    case MD_EXCEPTION_CODE_LIN_SIGVTALRM:
    case MD_EXCEPTION_CODE_LIN_SIGPROF:
    case MD_EXCEPTION_CODE_LIN_SIGWINCH:
    case MD_EXCEPTION_CODE_LIN_SIGIO:
    case MD_EXCEPTION_CODE_LIN_SIGPWR:
    case MD_EXCEPTION_CODE_LIN_SIGSYS:
    case MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED:
      return true;
    default:
      return false;
  }
}

}  // namespace google_breakpad
