minidump_fuzzer.cc 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <stddef.h>
  5. #include <stdint.h>
  6. #include <string.h>
  7. #include <istream>
  8. #include <limits>
  9. #include <memory>
  10. #include <streambuf>
  11. #include "base/memory/free_deleter.h"
  12. #include "google_breakpad/processor/basic_source_line_resolver.h"
  13. #include "google_breakpad/processor/minidump.h"
  14. #include "google_breakpad/processor/minidump_processor.h"
  15. #include "google_breakpad/processor/process_state.h"
  16. #include "processor/logging.h"
  17. #include "processor/simple_symbol_supplier.h"
  18. #include "processor/stackwalk_common.h"
  19. namespace {
  20. using google_breakpad::BasicSourceLineResolver;
  21. using google_breakpad::Minidump;
  22. using google_breakpad::MinidumpProcessor;
  23. using google_breakpad::ProcessState;
  24. using google_breakpad::SimpleSymbolSupplier;
  25. struct membuf : std::streambuf {
  26. membuf(char* begin, char* end) { setg(begin, begin, end); }
  27. protected:
  28. virtual pos_type seekoff(off_type off,
  29. std::ios_base::seekdir dir,
  30. std::ios_base::openmode which = std::ios_base::in) {
  31. if (dir == std::ios_base::cur)
  32. gbump(off);
  33. return gptr() - eback();
  34. }
  35. };
  36. bool PrintMinidumpProcess(const uint8_t* data,
  37. size_t size,
  38. const std::vector<string>& symbol_paths) {
  39. // Signature and version number.
  40. static const uint8_t kHeaderPrefix[] = {'P', 'M', 'D', 'M', 0, 0, 0xa7, 0x93};
  41. if (size > std::numeric_limits<size_t>::max() - sizeof(kHeaderPrefix))
  42. return false;
  43. size += sizeof(kHeaderPrefix);
  44. std::unique_ptr<char, base::FreeDeleter> buffer(
  45. static_cast<char*>(malloc(size)));
  46. if (!buffer)
  47. return false;
  48. memcpy(buffer.get(), kHeaderPrefix, sizeof(kHeaderPrefix));
  49. memcpy(buffer.get() + sizeof(kHeaderPrefix), data,
  50. size - sizeof(kHeaderPrefix));
  51. membuf sbuf(buffer.get(), buffer.get() + size);
  52. std::istream input(&sbuf);
  53. std::unique_ptr<SimpleSymbolSupplier> symbol_supplier;
  54. if (!symbol_paths.empty())
  55. symbol_supplier = std::make_unique<SimpleSymbolSupplier>(symbol_paths);
  56. BasicSourceLineResolver resolver;
  57. MinidumpProcessor minidump_processor(symbol_supplier.get(), &resolver);
  58. // Process the minidump.
  59. Minidump dump(input);
  60. if (!dump.Read()) {
  61. BPLOG(ERROR) << "Minidump " << dump.path() << " could not be read";
  62. return false;
  63. }
  64. ProcessState process_state;
  65. if (minidump_processor.Process(&dump, &process_state) !=
  66. google_breakpad::PROCESS_OK) {
  67. BPLOG(ERROR) << "MinidumpProcessor::Process failed";
  68. return false;
  69. }
  70. PrintProcessStateMachineReadable(process_state);
  71. return true;
  72. }
  73. } // namespace
  74. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  75. // TODO(wfh): Somehow pull symbols in.
  76. PrintMinidumpProcess(data, size, std::vector<string>());
  77. return 0;
  78. }