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 |