1 // Copyright 2012 Google LLC 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions are 5 // met: 6 // 7 // * Redistributions of source code must retain the above copyright 8 // notice, this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above 10 // copyright notice, this list of conditions and the following disclaimer 11 // in the documentation and/or other materials provided with the 12 // distribution. 13 // * Neither the name of Google LLC nor the names of its 14 // contributors may be used to endorse or promote products derived from 15 // this software without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 #ifndef CLIENT_LINUX_HANDLER_MINIDUMP_DESCRIPTOR_H_ 30 #define CLIENT_LINUX_HANDLER_MINIDUMP_DESCRIPTOR_H_ 31 32 #include <assert.h> 33 #include <sys/types.h> 34 35 #include <cstdint> 36 #include <string> 37 38 #include "client/linux/handler/microdump_extra_info.h" 39 #include "common/using_std_string.h" 40 41 // This class describes how a crash dump should be generated, either: 42 // - Writing a full minidump to a file in a given directory (the actual path, 43 // inside the directory, is determined by this class). 44 // - Writing a full minidump to a given fd. 45 // - Writing a reduced microdump to the console (logcat on Android). 46 namespace google_breakpad { 47 48 class MinidumpDescriptor { 49 public: 50 struct MicrodumpOnConsole {}; 51 static const MicrodumpOnConsole kMicrodumpOnConsole; 52 MinidumpDescriptor()53 MinidumpDescriptor() 54 : mode_(kUninitialized), 55 fd_(-1), 56 size_limit_(-1), 57 address_within_principal_mapping_(0), 58 skip_dump_if_principal_mapping_not_referenced_(false) {} 59 MinidumpDescriptor(const string & directory)60 explicit MinidumpDescriptor(const string& directory) 61 : mode_(kWriteMinidumpToFile), 62 fd_(-1), 63 directory_(directory), 64 c_path_(NULL), 65 size_limit_(-1), 66 address_within_principal_mapping_(0), 67 skip_dump_if_principal_mapping_not_referenced_(false), 68 sanitize_stacks_(false) { 69 assert(!directory.empty()); 70 } 71 MinidumpDescriptor(int fd)72 explicit MinidumpDescriptor(int fd) 73 : mode_(kWriteMinidumpToFd), 74 fd_(fd), 75 c_path_(NULL), 76 size_limit_(-1), 77 address_within_principal_mapping_(0), 78 skip_dump_if_principal_mapping_not_referenced_(false), 79 sanitize_stacks_(false) { 80 assert(fd != -1); 81 } 82 MinidumpDescriptor(const MicrodumpOnConsole &)83 explicit MinidumpDescriptor(const MicrodumpOnConsole&) 84 : mode_(kWriteMicrodumpToConsole), 85 fd_(-1), 86 size_limit_(-1), 87 address_within_principal_mapping_(0), 88 skip_dump_if_principal_mapping_not_referenced_(false), 89 sanitize_stacks_(false) {} 90 91 explicit MinidumpDescriptor(const MinidumpDescriptor& descriptor); 92 MinidumpDescriptor& operator=(const MinidumpDescriptor& descriptor); 93 94 static MinidumpDescriptor getMicrodumpDescriptor(); 95 IsFD()96 bool IsFD() const { return mode_ == kWriteMinidumpToFd; } 97 fd()98 int fd() const { return fd_; } 99 directory()100 string directory() const { return directory_; } 101 path()102 const char* path() const { return c_path_; } 103 IsMicrodumpOnConsole()104 bool IsMicrodumpOnConsole() const { 105 return mode_ == kWriteMicrodumpToConsole; 106 } 107 108 // Updates the path so it is unique. 109 // Should be called from a normal context: this methods uses the heap. 110 void UpdatePath(); 111 size_limit()112 off_t size_limit() const { return size_limit_; } set_size_limit(off_t limit)113 void set_size_limit(off_t limit) { size_limit_ = limit; } 114 address_within_principal_mapping()115 uintptr_t address_within_principal_mapping() const { 116 return address_within_principal_mapping_; 117 } set_address_within_principal_mapping(uintptr_t address_within_principal_mapping)118 void set_address_within_principal_mapping( 119 uintptr_t address_within_principal_mapping) { 120 address_within_principal_mapping_ = address_within_principal_mapping; 121 } 122 skip_dump_if_principal_mapping_not_referenced()123 bool skip_dump_if_principal_mapping_not_referenced() { 124 return skip_dump_if_principal_mapping_not_referenced_; 125 } set_skip_dump_if_principal_mapping_not_referenced(bool skip_dump_if_principal_mapping_not_referenced)126 void set_skip_dump_if_principal_mapping_not_referenced( 127 bool skip_dump_if_principal_mapping_not_referenced) { 128 skip_dump_if_principal_mapping_not_referenced_ = 129 skip_dump_if_principal_mapping_not_referenced; 130 } 131 sanitize_stacks()132 bool sanitize_stacks() const { return sanitize_stacks_; } set_sanitize_stacks(bool sanitize_stacks)133 void set_sanitize_stacks(bool sanitize_stacks) { 134 sanitize_stacks_ = sanitize_stacks; 135 } 136 microdump_extra_info()137 MicrodumpExtraInfo* microdump_extra_info() { 138 assert(IsMicrodumpOnConsole()); 139 return µdump_extra_info_; 140 } 141 142 private: 143 enum DumpMode { 144 kUninitialized = 0, 145 kWriteMinidumpToFile, 146 kWriteMinidumpToFd, 147 kWriteMicrodumpToConsole 148 }; 149 150 // Specifies the dump mode (see DumpMode). 151 DumpMode mode_; 152 153 // The file descriptor where the minidump is generated. 154 int fd_; 155 156 // The directory where the minidump should be generated. 157 string directory_; 158 159 // The full path to the generated minidump. 160 string path_; 161 162 // The C string of |path_|. Precomputed so it can be access from a compromised 163 // context. 164 const char* c_path_; 165 166 off_t size_limit_; 167 168 // This member points somewhere into the main module for this 169 // process (the module that is considerered interesting for the 170 // purposes of debugging crashes). 171 uintptr_t address_within_principal_mapping_; 172 173 // If set, threads that do not reference the address range 174 // associated with |address_within_principal_mapping_| will not have their 175 // stacks logged. 176 bool skip_dump_if_principal_mapping_not_referenced_; 177 178 // If set, stacks are sanitized to remove PII. This involves 179 // overwriting any pointer-aligned words that are not either 180 // pointers into a process mapping or small integers (+/-4096). This 181 // leaves enough information to unwind stacks, and preserve some 182 // register values, but elides strings and other program data. 183 bool sanitize_stacks_; 184 185 // The extra microdump data (e.g. product name/version, build 186 // fingerprint, gpu fingerprint) that should be appended to the dump 187 // (microdump only). Microdumps don't have the ability of appending 188 // extra metadata after the dump is generated (as opposite to 189 // minidumps MIME fields), therefore the extra data must be provided 190 // upfront. Any memory pointed to by members of the 191 // MicrodumpExtraInfo struct must be valid for the lifetime of the 192 // process (read: the caller has to guarantee that it is stored in 193 // global static storage.) 194 MicrodumpExtraInfo microdump_extra_info_; 195 }; 196 197 } // namespace google_breakpad 198 199 #endif // CLIENT_LINUX_HANDLER_MINIDUMP_DESCRIPTOR_H_ 200