aboutsummaryrefslogtreecommitdiff
path: root/src/google_breakpad/processor
diff options
context:
space:
mode:
authorLiu.andrew.x@gmail.com <Liu.andrew.x@gmail.com>2015-07-28 00:53:44 +0000
committerLiu.andrew.x@gmail.com <Liu.andrew.x@gmail.com>2015-07-28 00:53:44 +0000
commit2997f4590734f904190d46ee4ecf7dd4c8e5019b (patch)
treec6c27a3ae7e39b303bac1b25d46aef8c6b20962c /src/google_breakpad/processor
parentFix incorrect comment. (diff)
downloadbreakpad-2997f4590734f904190d46ee4ecf7dd4c8e5019b.tar.xz
Add support for Linux memory mapping stream and remove ELF header usage
when checking exploitability rating. Linux minidumps do not support MD_MEMORY_INFO_LIST_STREAM, meaning the processor cannot retrieve its memory mappings. However, it has its own stream, MD_LINUX_MAPS, which contains memory mappings specific to Linux (it contains the contents of /proc/self/maps). This CL allows the minidump to gather information from the memory mappings for Linux minidumps. In addition, exploitability rating for Linux dumps now use memory mappings instead of checking the ELF headers of binaries. The basis for the change is that checking the ELF headers requires the minidumps to store the memory from the ELF headers, while the memory mapping data is already present, meaning the size of a minidump will be unchanged. As a result, of removing ELF header analysis, two unit tests have been removed. Arguably, the cases that those unit tests check do not merit a high exploitability rating and do not warrant a solid conclusion that was given earlier. R=ivanpe@chromium.org Review URL: https://codereview.chromium.org/1251593007 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1476 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/google_breakpad/processor')
-rw-r--r--src/google_breakpad/processor/minidump.h103
-rw-r--r--src/google_breakpad/processor/proc_maps_linux.h57
2 files changed, 158 insertions, 2 deletions
diff --git a/src/google_breakpad/processor/minidump.h b/src/google_breakpad/processor/minidump.h
index 51f15025..9c8448a3 100644
--- a/src/google_breakpad/processor/minidump.h
+++ b/src/google_breakpad/processor/minidump.h
@@ -88,12 +88,14 @@
#include <string>
#include <vector>
+#include "common/basictypes.h"
#include "common/using_std_string.h"
#include "google_breakpad/processor/code_module.h"
#include "google_breakpad/processor/code_modules.h"
#include "google_breakpad/processor/dump_context.h"
#include "google_breakpad/processor/dump_object.h"
#include "google_breakpad/processor/memory_region.h"
+#include "google_breakpad/processor/proc_maps_linux.h"
namespace google_breakpad {
@@ -808,7 +810,7 @@ class MinidumpMemoryInfo : public MinidumpObject {
// These objects are managed by MinidumpMemoryInfoList.
friend class MinidumpMemoryInfoList;
- explicit MinidumpMemoryInfo(Minidump* minidump);
+ explicit MinidumpMemoryInfo(Minidump* minidump_);
// This works like MinidumpStream::Read, but is driven by
// MinidumpMemoryInfoList. No size checking is done, because
@@ -841,7 +843,7 @@ class MinidumpMemoryInfoList : public MinidumpStream {
static const uint32_t kStreamType = MD_MEMORY_INFO_LIST_STREAM;
- explicit MinidumpMemoryInfoList(Minidump* minidump);
+ explicit MinidumpMemoryInfoList(Minidump* minidump_);
bool Read(uint32_t expected_size);
@@ -852,6 +854,100 @@ class MinidumpMemoryInfoList : public MinidumpStream {
uint32_t info_count_;
};
+// MinidumpLinuxMaps wraps information about a single mapped memory region
+// from /proc/self/maps.
+class MinidumpLinuxMaps : public MinidumpObject {
+ public:
+ // The memory address of the base of the mapped region.
+ uint64_t GetBase() const { return valid_ ? region_.start : 0; }
+ // The size of the mapped region.
+ uint64_t GetSize() const { return valid_ ? region_.end - region_.start : 0; }
+
+ // The permissions of the mapped region.
+ bool IsReadable() const {
+ return valid_ ? region_.permissions & MappedMemoryRegion::READ : false;
+ }
+ bool IsWriteable() const {
+ return valid_ ? region_.permissions & MappedMemoryRegion::WRITE : false;
+ }
+ bool IsExecutable() const {
+ return valid_ ? region_.permissions & MappedMemoryRegion::EXECUTE : false;
+ }
+ bool IsPrivate() const {
+ return valid_ ? region_.permissions & MappedMemoryRegion::PRIVATE : false;
+ }
+
+ // The offset of the mapped region.
+ uint64_t GetOffset() const { return valid_ ? region_.offset : 0; }
+
+ // The major device number.
+ uint8_t GetMajorDevice() const { return valid_ ? region_.major_device : 0; }
+ // The minor device number.
+ uint8_t GetMinorDevice() const { return valid_ ? region_.minor_device : 0; }
+
+ // The inode of the mapped region.
+ uint64_t GetInode() const { return valid_ ? region_.inode : 0; }
+
+ // The pathname of the mapped region.
+ const string GetPathname() const { return valid_ ? region_.path : ""; }
+
+ // Print the contents of this mapping.
+ void Print();
+
+ private:
+ // These objects are managed by MinidumpLinuxMapsList.
+ friend class MinidumpLinuxMapsList;
+
+ // This caller owns the pointer.
+ explicit MinidumpLinuxMaps(Minidump *minidump);
+
+ // Read data about a single mapping from /proc/self/maps and load the data
+ // into this object. The input vector is in the same format as a line from
+ // /proc/self/maps.
+
+ // The memory region struct that this class wraps.
+ MappedMemoryRegion region_;
+
+ DISALLOW_COPY_AND_ASSIGN(MinidumpLinuxMaps);
+};
+
+// MinidumpLinuxMapsList corresponds to the Linux-exclusive MD_LINUX_MAPS
+// stream, which contains the contents of /prod/self/maps, which contains
+// the mapped memory regions and their access permissions.
+class MinidumpLinuxMapsList : public MinidumpStream {
+ public:
+ virtual ~MinidumpLinuxMapsList();
+
+ // Get mapping at the given memory address. The caller owns the pointer.
+ const MinidumpLinuxMaps *GetLinuxMapsForAddress(uint64_t address) const;
+ // Get mapping at the given index. The caller owns the pointer.
+ const MinidumpLinuxMaps *GetLinuxMapsAtIndex(unsigned int index) const;
+
+ // Print the contents of /proc/self/maps to stdout.
+ void Print();
+
+ private:
+ friend class Minidump;
+
+ typedef vector<MinidumpLinuxMaps *> MinidumpLinuxMappings;
+
+ static const uint32_t kStreamType = MD_LINUX_MAPS;
+
+ // The caller owns the pointer.
+ explicit MinidumpLinuxMapsList(Minidump *minidump);
+
+ // Read and load the contents of the process mapping data.
+ // The stream should have data in the form of /proc/self/maps.
+ // This method returns whether the stream was read successfully.
+ bool Read(uint32_t expected_size);
+
+ // The list of individual mappings.
+ MinidumpLinuxMappings *maps_;
+ // The number of mappings.
+ uint32_t maps_count_;
+
+ DISALLOW_COPY_AND_ASSIGN(MinidumpLinuxMapsList);
+};
// Minidump is the user's interface to a minidump file. It wraps MDRawHeader
// and provides access to the minidump's top-level stream directory.
@@ -912,6 +1008,9 @@ class Minidump {
virtual MinidumpBreakpadInfo* GetBreakpadInfo();
virtual MinidumpMemoryInfoList* GetMemoryInfoList();
+ // The next method also calls GetStream, but is exclusive for Linux dumps.
+ virtual MinidumpLinuxMapsList *GetLinuxMapsList();
+
// The next set of methods are provided for users who wish to access
// data in minidump files directly, while leveraging the rest of
// this class and related classes to handle the basic minidump
diff --git a/src/google_breakpad/processor/proc_maps_linux.h b/src/google_breakpad/processor/proc_maps_linux.h
new file mode 100644
index 00000000..6ddeb038
--- /dev/null
+++ b/src/google_breakpad/processor/proc_maps_linux.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_DEBUG_PROC_MAPS_LINUX_H_
+#define BASE_DEBUG_PROC_MAPS_LINUX_H_
+
+#include <string>
+#include <vector>
+
+#include "common/using_std_string.h"
+#include "google_breakpad/common/breakpad_types.h"
+
+namespace google_breakpad {
+
+// Describes a region of mapped memory and the path of the file mapped.
+struct MappedMemoryRegion {
+ enum Permission {
+ READ = 1 << 0,
+ WRITE = 1 << 1,
+ EXECUTE = 1 << 2,
+ PRIVATE = 1 << 3, // If set, region is private, otherwise it is shared.
+ };
+
+ // The address range [start,end) of mapped memory.
+ uintptr_t start;
+ uintptr_t end;
+
+ // Byte offset into |path| of the range mapped into memory.
+ uint64_t offset;
+
+ // Bitmask of read/write/execute/private/shared permissions.
+ uint8_t permissions;
+
+ // Major and minor devices.
+ uint8_t major_device;
+ uint8_t minor_device;
+
+ // Value of the inode.
+ uint64_t inode;
+
+ // Name of the file mapped into memory.
+ //
+ // NOTE: path names aren't guaranteed to point at valid files. For example,
+ // "[heap]" and "[stack]" are used to represent the location of the process'
+ // heap and stack, respectively.
+ string path;
+};
+
+// Parses /proc/<pid>/maps input data and stores in |regions|. Returns true
+// and updates |regions| if and only if all of |input| was successfully parsed.
+bool ParseProcMaps(const std::string& input,
+ std::vector<MappedMemoryRegion>* regions);
+
+} // namespace google_breakpad
+
+#endif // BASE_DEBUG_PROC_MAPS_LINUX_H_