Chromium Code Reviews| OLD | NEW |
|---|---|
| 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> |
| 11 #include <poll.h> | 11 #include <poll.h> |
| 12 #include <signal.h> | 12 #include <signal.h> |
| 13 #include <stddef.h> | 13 #include <stddef.h> |
| 14 #include <stdint.h> | 14 #include <stdint.h> |
| 15 #include <stdlib.h> | 15 #include <stdlib.h> |
| 16 #include <string.h> | 16 #include <string.h> |
| 17 #include <sys/socket.h> | 17 #include <sys/socket.h> |
| 18 #include <sys/time.h> | 18 #include <sys/time.h> |
| 19 #include <sys/types.h> | 19 #include <sys/types.h> |
| 20 #include <sys/uio.h> | 20 #include <sys/uio.h> |
| 21 #include <sys/wait.h> | 21 #include <sys/wait.h> |
| 22 #include <time.h> | 22 #include <time.h> |
| 23 #include <unistd.h> | 23 #include <unistd.h> |
| 24 | 24 |
| 25 #include <algorithm> | 25 #include <algorithm> |
| 26 #include <map> | |
| 26 #include <string> | 27 #include <string> |
| 27 | 28 |
| 28 #include "base/base_switches.h" | 29 #include "base/base_switches.h" |
| 29 #include "base/command_line.h" | 30 #include "base/command_line.h" |
| 30 #include "base/debug/crash_logging.h" | 31 #include "base/debug/crash_logging.h" |
| 31 #include "base/debug/dump_without_crashing.h" | 32 #include "base/debug/dump_without_crashing.h" |
| 32 #include "base/files/file_path.h" | 33 #include "base/files/file_path.h" |
| 34 #include "base/format_macros.h" | |
| 33 #include "base/lazy_instance.h" | 35 #include "base/lazy_instance.h" |
| 34 #include "base/linux_util.h" | 36 #include "base/linux_util.h" |
| 35 #include "base/macros.h" | 37 #include "base/macros.h" |
| 36 #include "base/path_service.h" | 38 #include "base/path_service.h" |
| 37 #include "base/posix/eintr_wrapper.h" | 39 #include "base/posix/eintr_wrapper.h" |
| 38 #include "base/posix/global_descriptors.h" | 40 #include "base/posix/global_descriptors.h" |
| 39 #include "base/process/memory.h" | 41 #include "base/process/memory.h" |
| 40 #include "base/strings/string_split.h" | 42 #include "base/strings/string_split.h" |
| 41 #include "base/strings/string_util.h" | 43 #include "base/strings/string_util.h" |
| 44 #include "base/strings/stringprintf.h" | |
| 42 #include "base/threading/thread_checker.h" | 45 #include "base/threading/thread_checker.h" |
| 43 #include "breakpad/src/client/linux/crash_generation/crash_generation_client.h" | 46 #include "breakpad/src/client/linux/crash_generation/crash_generation_client.h" |
| 44 #include "breakpad/src/client/linux/handler/exception_handler.h" | 47 #include "breakpad/src/client/linux/handler/exception_handler.h" |
| 45 #include "breakpad/src/client/linux/minidump_writer/directory_reader.h" | 48 #include "breakpad/src/client/linux/minidump_writer/directory_reader.h" |
| 46 #include "breakpad/src/common/linux/linux_libc_support.h" | 49 #include "breakpad/src/common/linux/linux_libc_support.h" |
| 47 #include "breakpad/src/common/memory.h" | 50 #include "breakpad/src/common/memory.h" |
| 48 #include "build/build_config.h" | 51 #include "build/build_config.h" |
| 49 #include "components/crash/content/app/breakpad_linux_impl.h" | 52 #include "components/crash/content/app/breakpad_linux_impl.h" |
| 50 #include "components/crash/content/app/crash_reporter_client.h" | 53 #include "components/crash/content/app/crash_reporter_client.h" |
| 51 #include "components/crash/core/common/crash_keys.h" | 54 #include "components/crash/core/common/crash_keys.h" |
| (...skipping 1039 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1091 MinidumpDescriptor("/tmp"), // Unused but needed or Breakpad will assert. | 1094 MinidumpDescriptor("/tmp"), // Unused but needed or Breakpad will assert. |
| 1092 nullptr, | 1095 nullptr, |
| 1093 nullptr, | 1096 nullptr, |
| 1094 nullptr, | 1097 nullptr, |
| 1095 true, | 1098 true, |
| 1096 -1); | 1099 -1); |
| 1097 g_breakpad->set_crash_generation_client(new NonBrowserCrashHandler()); | 1100 g_breakpad->set_crash_generation_client(new NonBrowserCrashHandler()); |
| 1098 } | 1101 } |
| 1099 #endif // defined(OS_ANDROID) | 1102 #endif // defined(OS_ANDROID) |
| 1100 | 1103 |
| 1104 std::unordered_set<std::string> g_crash_keys_whitelist; | |
|
gsennton
2017/02/27 18:31:37
I'm not sure what constraints we have on what data
Robert Sesek
2017/02/27 23:15:28
Basically nothing that allocates, if possible. Cre
gsennton
2017/02/28 21:02:42
This should be fine now :).
Tobias Sargeant
2017/02/28 22:18:55
I think Robert's suggestion of a NULL terminated C
Robert Sesek
2017/03/02 15:00:38
No, crash keys can be set in a compromised context
gsennton
2017/03/02 16:18:01
I changed the vector to a NULL terminated C array
| |
| 1105 | |
| 1106 // TODO copy-pasted from base/debug/crash_logging.cc, can we just BASE_EXPORT | |
| 1107 // that implementation instead? | |
|
gsennton
2017/02/27 18:31:38
^^^ is BASE_EXPORTING NumChunksForLength OK?
Robert Sesek
2017/02/27 23:15:28
Hm, it should be OK. What keys are going to be whi
gsennton
2017/02/28 21:02:42
Removed these - with a more hard-coded (ugh!) vers
| |
| 1108 size_t NumChunksForLength(size_t length, size_t chunk_max_length) { | |
| 1109 // Compute (length / g_chunk_max_length_), rounded up. | |
| 1110 return (length + chunk_max_length - 1) / chunk_max_length; | |
| 1111 } | |
| 1112 | |
| 1113 // TODO also copy-pasted from base/debug/crash_logging.cc | |
| 1114 const char kChunkFormatString[] = "%s-%" PRIuS; | |
|
gsennton
2017/02/27 18:31:38
^^ same question here, should we BASE_EXPORT this?
| |
| 1115 | |
| 1116 void SetupCrashKeysWhiteList(const std::vector<base::debug::CrashKey>& keys, | |
| 1117 const size_t chunk_max_length) { | |
| 1118 LOG(ERROR) << "in SetupCrashKeysWhiteList"; | |
| 1119 // TODO do we care that we are storing lots of keys in our map? | |
|
gsennton
2017/02/27 18:31:38
In our whitelist set we are storing an entry for e
Robert Sesek
2017/02/27 23:15:28
I think it's fine to just have up to 16 entries. H
gsennton
2017/02/28 21:02:42
+1, no large keys.
gsennton
2017/02/28 21:02:42
Yeah, we only whitelist small/medium-sized keys, s
| |
| 1120 for (size_t key_index = 0; key_index < keys.size(); ++key_index) { | |
| 1121 const size_t num_chunks = | |
| 1122 NumChunksForLength(keys[key_index].max_length, chunk_max_length); | |
| 1123 if (num_chunks == 1) { | |
| 1124 g_crash_keys_whitelist.insert(keys[key_index].key_name); | |
| 1125 } else { | |
| 1126 for (size_t chunk_index = 0; chunk_index < num_chunks; ++chunk_index) { | |
| 1127 g_crash_keys_whitelist.insert(base::StringPrintf( | |
| 1128 kChunkFormatString, keys[key_index].key_name, chunk_index + 1)); | |
| 1129 } | |
| 1130 } | |
| 1131 } | |
| 1132 LOG(ERROR) << "in SetupCrashKeysWhiteList, whitelist length: " | |
| 1133 << g_crash_keys_whitelist.size(); | |
| 1134 for (auto it = g_crash_keys_whitelist.begin(); | |
| 1135 it != g_crash_keys_whitelist.end(); it++) { | |
| 1136 LOG(ERROR) << "in SetupCrashKeysWhiteList, entry: " << *it; | |
| 1137 } | |
| 1138 } | |
| 1139 | |
| 1140 bool IsInWhiteList(const base::StringPiece& key) { | |
| 1141 // TODO does this need to be thread-safe? | |
|
gsennton
2017/02/27 18:31:38
I'm guessing we allow SetCrashKeyValue to be calle
Robert Sesek
2017/02/27 23:15:28
Yup. I'd ensure the whitelist is immutable after i
gsennton
2017/02/28 21:02:42
Done (well, I don't touch it again after the initi
| |
| 1142 return g_crash_keys_whitelist.find(key.as_string()) != | |
| 1143 g_crash_keys_whitelist.end(); | |
| 1144 } | |
| 1145 | |
| 1101 void SetCrashKeyValue(const base::StringPiece& key, | 1146 void SetCrashKeyValue(const base::StringPiece& key, |
| 1102 const base::StringPiece& value) { | 1147 const base::StringPiece& value) { |
| 1103 g_crash_keys->SetKeyValue(key.data(), value.data()); | 1148 LOG(ERROR) << "in SetCrashKeyValue for key " << key.data(); |
| 1149 // TODO if #DEFINED(USE_WHITELIST) --use-whitelist | |
| 1150 if (IsInWhiteList(key)) { | |
| 1151 LOG(ERROR) << "in SetCrashKeyValue for key " << key.data() | |
| 1152 << " it is in the whitelist :D"; | |
| 1153 g_crash_keys->SetKeyValue(key.data(), value.data()); | |
| 1154 } else { | |
| 1155 LOG(ERROR) << "in SetCrashKeyValue for key " << key.data() | |
| 1156 << ", not in the whitelist"; | |
| 1157 } | |
| 1104 } | 1158 } |
| 1105 | 1159 |
| 1106 void ClearCrashKey(const base::StringPiece& key) { | 1160 void ClearCrashKey(const base::StringPiece& key) { |
| 1107 g_crash_keys->RemoveKey(key.data()); | 1161 g_crash_keys->RemoveKey(key.data()); |
| 1108 } | 1162 } |
| 1109 | 1163 |
| 1110 // GetCrashReporterClient() cannot call any Set methods until after | 1164 // GetCrashReporterClient() cannot call any Set methods until after |
| 1111 // InitCrashKeys(). | 1165 // InitCrashKeys(). |
| 1112 void InitCrashKeys() { | 1166 void InitCrashKeys() { |
| 1113 g_crash_keys = new CrashKeyStorage; | 1167 g_crash_keys = new CrashKeyStorage; |
| 1114 GetCrashReporterClient()->RegisterCrashKeys(); | 1168 GetCrashReporterClient()->RegisterCrashKeys(); |
| 1169 // TODO if #DEFINED(USE_WHITELIST) --use-whitelist | |
| 1170 SetupCrashKeysWhiteList(GetCrashReporterClient()->GetWhiteListedCrashKeys(), | |
| 1171 crash_keys::kChunkMaxLength); | |
| 1115 base::debug::SetCrashKeyReportingFunctions(&SetCrashKeyValue, &ClearCrashKey); | 1172 base::debug::SetCrashKeyReportingFunctions(&SetCrashKeyValue, &ClearCrashKey); |
| 1116 } | 1173 } |
| 1117 | 1174 |
| 1118 // Miscellaneous initialization functions to call after Breakpad has been | 1175 // Miscellaneous initialization functions to call after Breakpad has been |
| 1119 // enabled. | 1176 // enabled. |
| 1120 void PostEnableBreakpadInitialization() { | 1177 void PostEnableBreakpadInitialization() { |
| 1121 SetProcessStartTime(); | 1178 SetProcessStartTime(); |
| 1122 g_pid = getpid(); | 1179 g_pid = getpid(); |
| 1123 | 1180 |
| 1124 base::debug::SetDumpWithoutCrashingFunction(&DumpProcess); | 1181 base::debug::SetDumpWithoutCrashingFunction(&DumpProcess); |
| (...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2059 void SuppressDumpGeneration() { | 2116 void SuppressDumpGeneration() { |
| 2060 g_dumps_suppressed = G_DUMPS_SUPPRESSED_MAGIC; | 2117 g_dumps_suppressed = G_DUMPS_SUPPRESSED_MAGIC; |
| 2061 } | 2118 } |
| 2062 #endif // OS_ANDROID | 2119 #endif // OS_ANDROID |
| 2063 | 2120 |
| 2064 bool IsCrashReporterEnabled() { | 2121 bool IsCrashReporterEnabled() { |
| 2065 return g_is_crash_reporter_enabled; | 2122 return g_is_crash_reporter_enabled; |
| 2066 } | 2123 } |
| 2067 | 2124 |
| 2068 } // namespace breakpad | 2125 } // namespace breakpad |
| OLD | NEW |