// 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 "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 == NULL) {
    BPLOG(INFO) << "No exception record.";
    return EXPLOITABILITY_ERR_PROCESSING;
  }
  const MDRawExceptionStream* raw_exception_stream = exception->exception();
  if (raw_exception_stream == NULL) {
    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 == NULL) {
    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) : NULL;
  if (!memory_region) {
    BPLOG(INFO) << "No memory region around instruction pointer.";
    return false;
  }

  // Get exception data to find architecture.
  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) : NULL;
  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
