Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(960)

Side by Side Diff: components/crash/content/app/breakpad_linux.cc

Issue 2652133004: Sanitize mini- and microdumps for webview (Closed)
Patch Set: Address review comments. Also apply settings when g_breakpad is constructed. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // For linux_syscall_support.h. This makes it safe to call embedded system 5 // For linux_syscall_support.h. This makes it safe to call embedded system
6 // calls when in seccomp mode. 6 // calls when in seccomp mode.
7 7
8 #include "components/crash/content/app/breakpad_linux.h" 8 #include "components/crash/content/app/breakpad_linux.h"
9 9
10 #include <fcntl.h> 10 #include <fcntl.h>
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 uint32_t g_dumps_suppressed = 0; 106 uint32_t g_dumps_suppressed = 0;
107 char* g_process_type = nullptr; 107 char* g_process_type = nullptr;
108 ExceptionHandler* g_microdump = nullptr; 108 ExceptionHandler* g_microdump = nullptr;
109 int g_signal_code_pipe_fd = -1; 109 int g_signal_code_pipe_fd = -1;
110 110
111 class MicrodumpInfo { 111 class MicrodumpInfo {
112 public: 112 public:
113 MicrodumpInfo() 113 MicrodumpInfo()
114 : microdump_build_fingerprint_(nullptr), 114 : microdump_build_fingerprint_(nullptr),
115 microdump_product_info_(nullptr), 115 microdump_product_info_(nullptr),
116 microdump_gpu_fingerprint_(nullptr) {} 116 microdump_gpu_fingerprint_(nullptr),
117 microdump_process_type_(nullptr),
118 skip_dump_if_principal_mapping_not_referenced_(false),
119 address_within_principal_mapping_(0ul),
120 should_sanitize_dumps_(false) {}
117 121
118 // The order in which SetGpuFingerprint and Initialize are called 122 // The order in which SetGpuFingerprint and Initialize are called
119 // may be dependent on the timing of the availability of GPU 123 // may be dependent on the timing of the availability of GPU
120 // information. For this reason, they can be called in either order, 124 // information. For this reason, they can be called in either order,
121 // resulting in the same effect. 125 // resulting in the same effect.
122 // 126 //
123 // The following restrictions apply, however: 127 // The following restrictions apply, however:
124 // * Both methods must be called from the same thread. 128 // * Both methods must be called from the same thread.
125 // * Both methods must be called at most once. 129 // * Both methods must be called at most once.
126 // 130 //
127 // Microdumps will only be generated if Initialize is called. If 131 // Microdumps will only be generated if Initialize is called. If
128 // SetGpuFingerprint has not been called called at the point at 132 // SetGpuFingerprint has not been called called at the point at
129 // which a microdump is generated, then the GPU fingerprint will be 133 // which a microdump is generated, then the GPU fingerprint will be
130 // UNKNOWN. 134 // UNKNOWN.
131 void SetGpuFingerprint(const std::string& gpu_fingerprint); 135 void SetGpuFingerprint(const std::string& gpu_fingerprint);
136 void SetSkipDumpIfPrincipalMappingNotReferenced(
137 uintptr_t address_within_principal_mapping);
138 void SetShouldSanitizeDumps(bool should_sanitize_dumps);
139 void UpdateMinidumpDescriptor(MinidumpDescriptor* minidump_descriptor);
140 void UpdateExceptionHandlers();
132 void Initialize(const std::string& process_type, 141 void Initialize(const std::string& process_type,
133 const char* product_name, 142 const char* product_name,
134 const char* product_version, 143 const char* product_version,
135 const char* android_build_fp); 144 const char* android_build_fp);
136 145
137 private: 146 private:
138 base::ThreadChecker thread_checker_; 147 base::ThreadChecker thread_checker_;
139 const char* microdump_build_fingerprint_; 148 const char* microdump_build_fingerprint_;
140 const char* microdump_product_info_; 149 const char* microdump_product_info_;
141 const char* microdump_gpu_fingerprint_; 150 const char* microdump_gpu_fingerprint_;
142 const char* microdump_process_type_; 151 const char* microdump_process_type_;
152 bool skip_dump_if_principal_mapping_not_referenced_;
153 uintptr_t address_within_principal_mapping_;
154 bool should_sanitize_dumps_;
143 }; 155 };
144 156
145 base::LazyInstance<MicrodumpInfo> g_microdump_info = 157 base::LazyInstance<MicrodumpInfo> g_microdump_info =
146 LAZY_INSTANCE_INITIALIZER; 158 LAZY_INSTANCE_INITIALIZER;
147 159
148 #endif 160 #endif
149 161
150 CrashKeyStorage* g_crash_keys = nullptr; 162 CrashKeyStorage* g_crash_keys = nullptr;
151 163
152 // Writes the value |v| as 16 hex characters to the memory pointed at by 164 // Writes the value |v| as 16 hex characters to the memory pointed at by
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 void* context, 735 void* context,
724 bool succeeded) { 736 bool succeeded) {
725 return CrashDone(minidump, true, true, succeeded); 737 return CrashDone(minidump, true, true, succeeded);
726 } 738 }
727 #endif 739 #endif
728 740
729 void DumpProcess() { 741 void DumpProcess() {
730 #if defined(OS_ANDROID) 742 #if defined(OS_ANDROID)
731 // Don't use g_breakpad and g_microdump directly here, because their 743 // Don't use g_breakpad and g_microdump directly here, because their
732 // output might currently be suppressed. 744 // output might currently be suppressed.
733 if (g_breakpad) { 745
746 // If a breakpad handler is installed, but its target is a file
747 // descriptor, we can't generate a dump because we can't risk
748 // writing multiple minidumps to the FD, so it can only be used for
749 // dumps that are associated with a crash.
750 if (g_breakpad && !g_breakpad->minidump_descriptor().IsFD()) {
734 ExceptionHandler(g_breakpad->minidump_descriptor(), 751 ExceptionHandler(g_breakpad->minidump_descriptor(),
735 nullptr, 752 nullptr,
736 CrashDoneNoUpload, 753 CrashDoneNoUpload,
737 nullptr, 754 nullptr,
738 false, -1).WriteMinidump(); 755 false, -1).WriteMinidump();
739 } 756 }
740 // If microdumps are enabled write also a microdump on the system log. 757 // If microdumps are enabled write also a microdump on the system log.
741 if (g_microdump) { 758 if (g_microdump) {
742 ExceptionHandler(g_microdump->minidump_descriptor(), 759 ExceptionHandler(g_microdump->minidump_descriptor(),
743 nullptr, 760 nullptr,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 DCHECK(!g_breakpad); 798 DCHECK(!g_breakpad);
782 MinidumpDescriptor minidump_descriptor(dumps_path.value()); 799 MinidumpDescriptor minidump_descriptor(dumps_path.value());
783 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 800 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
784 switches::kFullMemoryCrashReport)) { 801 switches::kFullMemoryCrashReport)) {
785 minidump_descriptor.set_size_limit(-1); // unlimited. 802 minidump_descriptor.set_size_limit(-1); // unlimited.
786 } else { 803 } else {
787 minidump_descriptor.set_size_limit(kMaxMinidumpFileSize); 804 minidump_descriptor.set_size_limit(kMaxMinidumpFileSize);
788 } 805 }
789 #if defined(OS_ANDROID) 806 #if defined(OS_ANDROID)
790 unattended = true; // Android never uploads directly. 807 unattended = true; // Android never uploads directly.
808 g_microdump_info.Get().UpdateMinidumpDescriptor(&minidump_descriptor);
791 #endif 809 #endif
792 if (unattended) { 810 if (unattended) {
793 g_breakpad = new ExceptionHandler( 811 g_breakpad = new ExceptionHandler(
794 minidump_descriptor, 812 minidump_descriptor,
795 #if defined(OS_ANDROID) 813 #if defined(OS_ANDROID)
796 ShouldGenerateDump, 814 ShouldGenerateDump,
797 #else 815 #else
798 nullptr, 816 nullptr,
799 #endif 817 #endif
800 CrashDoneNoUpload, 818 CrashDoneNoUpload,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 return false; 852 return false;
835 } 853 }
836 854
837 bool CrashDoneInProcessNoUpload( 855 bool CrashDoneInProcessNoUpload(
838 const google_breakpad::MinidumpDescriptor& descriptor, 856 const google_breakpad::MinidumpDescriptor& descriptor,
839 void* context, 857 void* context,
840 const bool succeeded) { 858 const bool succeeded) {
841 // WARNING: this code runs in a compromised context. It may not call into 859 // WARNING: this code runs in a compromised context. It may not call into
842 // libc nor allocate memory normally. 860 // libc nor allocate memory normally.
843 if (!succeeded) { 861 if (!succeeded) {
844 static const char msg[] = "Crash dump generation failed.\n"; 862 if (ShouldGenerateDump(nullptr)) {
845 WriteLog(msg, sizeof(msg) - 1); 863 static const char msg[] = "Crash dump generation failed.\n";
864 WriteLog(msg, sizeof(msg) - 1);
865 }
846 return false; 866 return false;
847 } 867 }
848 868
849 // Start constructing the message to send to the browser. 869 // Start constructing the message to send to the browser.
850 BreakpadInfo info = {0}; 870 BreakpadInfo info = {0};
851 info.filename = nullptr; 871 info.filename = nullptr;
852 info.fd = descriptor.fd(); 872 info.fd = descriptor.fd();
853 info.process_type = g_process_type; 873 info.process_type = g_process_type;
854 info.process_type_length = my_strlen(g_process_type); 874 info.process_type_length = my_strlen(g_process_type);
855 info.distro = nullptr; 875 info.distro = nullptr;
(...skipping 27 matching lines...) Expand all
883 return; 903 return;
884 } 904 }
885 SetProcessStartTime(); 905 SetProcessStartTime();
886 g_pid = getpid(); 906 g_pid = getpid();
887 907
888 g_is_crash_reporter_enabled = true; 908 g_is_crash_reporter_enabled = true;
889 // Save the process type (it is leaked). 909 // Save the process type (it is leaked).
890 const size_t process_type_len = process_type.size() + 1; 910 const size_t process_type_len = process_type.size() + 1;
891 g_process_type = new char[process_type_len]; 911 g_process_type = new char[process_type_len];
892 strncpy(g_process_type, process_type.c_str(), process_type_len); 912 strncpy(g_process_type, process_type.c_str(), process_type_len);
893 new ExceptionHandler(MinidumpDescriptor(minidump_fd), ShouldGenerateDump, 913
894 CrashDoneInProcessNoUpload, nullptr, true, -1); 914 MinidumpDescriptor descriptor(minidump_fd);
915 g_microdump_info.Get().UpdateMinidumpDescriptor(&descriptor);
916 g_breakpad =
917 new ExceptionHandler(descriptor, ShouldGenerateDump,
918 CrashDoneInProcessNoUpload, nullptr, true, -1);
895 } 919 }
896 920
897 void MicrodumpInfo::SetGpuFingerprint(const std::string& gpu_fingerprint) { 921 void MicrodumpInfo::SetGpuFingerprint(const std::string& gpu_fingerprint) {
898 DCHECK(thread_checker_.CalledOnValidThread()); 922 DCHECK(thread_checker_.CalledOnValidThread());
899 DCHECK(!microdump_gpu_fingerprint_); 923 DCHECK(!microdump_gpu_fingerprint_);
900 microdump_gpu_fingerprint_ = strdup(gpu_fingerprint.c_str()); 924 microdump_gpu_fingerprint_ = strdup(gpu_fingerprint.c_str());
901 ANNOTATE_LEAKING_OBJECT_PTR(microdump_gpu_fingerprint_); 925 ANNOTATE_LEAKING_OBJECT_PTR(microdump_gpu_fingerprint_);
902 926
927 UpdateExceptionHandlers();
928 }
929
930 void MicrodumpInfo::SetSkipDumpIfPrincipalMappingNotReferenced(
931 uintptr_t address_within_principal_mapping) {
932 DCHECK(thread_checker_.CalledOnValidThread());
933 skip_dump_if_principal_mapping_not_referenced_ = true;
934 address_within_principal_mapping_ = address_within_principal_mapping;
935
936 UpdateExceptionHandlers();
937 }
938
939 void MicrodumpInfo::SetShouldSanitizeDumps(bool should_sanitize_dumps) {
940 DCHECK(thread_checker_.CalledOnValidThread());
941 should_sanitize_dumps_ = should_sanitize_dumps;
942
943 UpdateExceptionHandlers();
944 }
945
946 void MicrodumpInfo::UpdateMinidumpDescriptor(
947 MinidumpDescriptor* minidump_descriptor) {
948 google_breakpad::MicrodumpExtraInfo* microdump_extra_info =
949 minidump_descriptor->microdump_extra_info();
950
951 minidump_descriptor->set_skip_dump_if_principal_mapping_not_referenced(
952 skip_dump_if_principal_mapping_not_referenced_);
953 minidump_descriptor->set_address_within_principal_mapping(
954 address_within_principal_mapping_);
955 minidump_descriptor->set_sanitize_stacks(should_sanitize_dumps_);
956
957 microdump_extra_info->gpu_fingerprint = microdump_gpu_fingerprint_;
958 microdump_extra_info->product_info = microdump_product_info_;
959 microdump_extra_info->process_type = microdump_process_type_;
960 microdump_extra_info->build_fingerprint = microdump_build_fingerprint_;
961 }
962
963 void MicrodumpInfo::UpdateExceptionHandlers() {
964 if (g_breakpad) {
965 MinidumpDescriptor descriptor(g_breakpad->minidump_descriptor());
966 UpdateMinidumpDescriptor(&descriptor);
967 g_breakpad->set_minidump_descriptor(descriptor);
968 }
903 if (g_microdump) { 969 if (g_microdump) {
904 MinidumpDescriptor minidump_descriptor(g_microdump->minidump_descriptor()); 970 MinidumpDescriptor descriptor(g_microdump->minidump_descriptor());
905 minidump_descriptor.microdump_extra_info()->gpu_fingerprint = 971 UpdateMinidumpDescriptor(&descriptor);
906 microdump_gpu_fingerprint_; 972 g_microdump->set_minidump_descriptor(descriptor);
907 g_microdump->set_minidump_descriptor(minidump_descriptor);
908 } 973 }
909 } 974 }
910 975
911 void MicrodumpInfo::Initialize(const std::string& process_type, 976 void MicrodumpInfo::Initialize(const std::string& process_type,
912 const char* product_name, 977 const char* product_name,
913 const char* product_version, 978 const char* product_version,
914 const char* android_build_fp) { 979 const char* android_build_fp) {
915 DCHECK(thread_checker_.CalledOnValidThread()); 980 DCHECK(thread_checker_.CalledOnValidThread());
916 DCHECK(!g_microdump); 981 DCHECK(!g_microdump);
917 // |process_type| for webview's browser process is kBrowserProcessType or 982 // |process_type| for webview's browser process is kBrowserProcessType or
918 // kWebViewSingleProcessType. |process_type| for chrome's browser process is 983 // kWebViewSingleProcessType. |process_type| for chrome's browser process is
919 // an empty string. 984 // an empty string.
920 bool is_browser_process = process_type.empty() || 985 bool is_browser_process = process_type.empty() ||
921 process_type == kWebViewSingleProcessType || 986 process_type == kWebViewSingleProcessType ||
922 process_type == kBrowserProcessType; 987 process_type == kBrowserProcessType;
923 988
924 MinidumpDescriptor descriptor(MinidumpDescriptor::kMicrodumpOnConsole); 989 MinidumpDescriptor descriptor(MinidumpDescriptor::kMicrodumpOnConsole);
925 990
926 if (product_name && product_version) { 991 if (product_name && product_version) {
927 microdump_product_info_ = 992 microdump_product_info_ =
928 strdup((product_name + std::string(":") + product_version).c_str()); 993 strdup((product_name + std::string(":") + product_version).c_str());
929 ANNOTATE_LEAKING_OBJECT_PTR(microdump_product_info_); 994 ANNOTATE_LEAKING_OBJECT_PTR(microdump_product_info_);
930 descriptor.microdump_extra_info()->product_info = microdump_product_info_;
931 } 995 }
932 996
933 microdump_process_type_ = 997 microdump_process_type_ =
934 strdup(process_type.empty() ? kBrowserProcessType : process_type.c_str()); 998 strdup(process_type.empty() ? kBrowserProcessType : process_type.c_str());
935 ANNOTATE_LEAKING_OBJECT_PTR(microdump_process_type_); 999 ANNOTATE_LEAKING_OBJECT_PTR(microdump_process_type_);
936 descriptor.microdump_extra_info()->process_type = microdump_process_type_;
937 1000
938 if (android_build_fp) { 1001 if (android_build_fp) {
939 microdump_build_fingerprint_ = strdup(android_build_fp); 1002 microdump_build_fingerprint_ = strdup(android_build_fp);
940 ANNOTATE_LEAKING_OBJECT_PTR(microdump_build_fingerprint_); 1003 ANNOTATE_LEAKING_OBJECT_PTR(microdump_build_fingerprint_);
941 descriptor.microdump_extra_info()->build_fingerprint =
942 microdump_build_fingerprint_;
943 } 1004 }
944 1005
945 if (microdump_gpu_fingerprint_) { 1006 UpdateMinidumpDescriptor(&descriptor);
946 descriptor.microdump_extra_info()->gpu_fingerprint =
947 microdump_gpu_fingerprint_;
948 }
949 1007
950 g_microdump = 1008 g_microdump =
951 new ExceptionHandler(descriptor, ShouldGenerateDump, MicrodumpCrashDone, 1009 new ExceptionHandler(descriptor, ShouldGenerateDump, MicrodumpCrashDone,
952 reinterpret_cast<void*>(is_browser_process), 1010 reinterpret_cast<void*>(is_browser_process),
953 true, // Install handlers. 1011 true, // Install handlers.
954 -1); // Server file descriptor. -1 for in-process. 1012 -1); // Server file descriptor. -1 for in-process.
955 1013
956 if (process_type != kWebViewSingleProcessType && 1014 if (process_type != kWebViewSingleProcessType &&
957 process_type != kBrowserProcessType && 1015 process_type != kBrowserProcessType &&
958 !process_type.empty()) { 1016 !process_type.empty()) {
(...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after
1996 minidump_descriptor.set_size_limit(-1); 2054 minidump_descriptor.set_size_limit(-1);
1997 ExceptionHandler(minidump_descriptor, nullptr, MinidumpGenerated, nullptr, 2055 ExceptionHandler(minidump_descriptor, nullptr, MinidumpGenerated, nullptr,
1998 false, -1) 2056 false, -1)
1999 .WriteMinidump(); 2057 .WriteMinidump();
2000 } 2058 }
2001 } 2059 }
2002 2060
2003 void SuppressDumpGeneration() { 2061 void SuppressDumpGeneration() {
2004 g_dumps_suppressed = G_DUMPS_SUPPRESSED_MAGIC; 2062 g_dumps_suppressed = G_DUMPS_SUPPRESSED_MAGIC;
2005 } 2063 }
2064
2065 void SetSkipDumpIfPrincipalMappingNotReferenced(
2066 uintptr_t address_within_principal_mapping) {
2067 g_microdump_info.Get().SetSkipDumpIfPrincipalMappingNotReferenced(
2068 address_within_principal_mapping);
2069 }
2070
2071 void SetShouldSanitizeDumps(bool should_sanitize_dumps) {
2072 g_microdump_info.Get().SetShouldSanitizeDumps(should_sanitize_dumps);
2073 }
2006 #endif // OS_ANDROID 2074 #endif // OS_ANDROID
2007 2075
2008 bool IsCrashReporterEnabled() { 2076 bool IsCrashReporterEnabled() {
2009 return g_is_crash_reporter_enabled; 2077 return g_is_crash_reporter_enabled;
2010 } 2078 }
2011 2079
2012 } // namespace breakpad 2080 } // namespace breakpad
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698