Index: components/crash/content/app/breakpad_linux.cc |
diff --git a/components/crash/content/app/breakpad_linux.cc b/components/crash/content/app/breakpad_linux.cc |
index 3c31d7619e49bf56210ff310e3a73905c58a43ec..29480131e43f1a47fefe4963d0d0d00f55862ba0 100644 |
--- a/components/crash/content/app/breakpad_linux.cc |
+++ b/components/crash/content/app/breakpad_linux.cc |
@@ -23,6 +23,7 @@ |
#include <unistd.h> |
#include <algorithm> |
+#include <map> |
#include <string> |
#include "base/base_switches.h" |
@@ -30,6 +31,7 @@ |
#include "base/debug/crash_logging.h" |
#include "base/debug/dump_without_crashing.h" |
#include "base/files/file_path.h" |
+#include "base/format_macros.h" |
#include "base/lazy_instance.h" |
#include "base/linux_util.h" |
#include "base/macros.h" |
@@ -39,6 +41,7 @@ |
#include "base/process/memory.h" |
#include "base/strings/string_split.h" |
#include "base/strings/string_util.h" |
+#include "base/strings/stringprintf.h" |
#include "base/threading/thread_checker.h" |
#include "breakpad/src/client/linux/crash_generation/crash_generation_client.h" |
#include "breakpad/src/client/linux/handler/exception_handler.h" |
@@ -1098,9 +1101,60 @@ void EnableNonBrowserCrashDumping() { |
} |
#endif // defined(OS_ANDROID) |
+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
|
+ |
+// TODO copy-pasted from base/debug/crash_logging.cc, can we just BASE_EXPORT |
+// 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
|
+size_t NumChunksForLength(size_t length, size_t chunk_max_length) { |
+ // Compute (length / g_chunk_max_length_), rounded up. |
+ return (length + chunk_max_length - 1) / chunk_max_length; |
+} |
+ |
+// TODO also copy-pasted from base/debug/crash_logging.cc |
+const char kChunkFormatString[] = "%s-%" PRIuS; |
gsennton
2017/02/27 18:31:38
^^ same question here, should we BASE_EXPORT this?
|
+ |
+void SetupCrashKeysWhiteList(const std::vector<base::debug::CrashKey>& keys, |
+ const size_t chunk_max_length) { |
+ LOG(ERROR) << "in SetupCrashKeysWhiteList"; |
+ // 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
|
+ for (size_t key_index = 0; key_index < keys.size(); ++key_index) { |
+ const size_t num_chunks = |
+ NumChunksForLength(keys[key_index].max_length, chunk_max_length); |
+ if (num_chunks == 1) { |
+ g_crash_keys_whitelist.insert(keys[key_index].key_name); |
+ } else { |
+ for (size_t chunk_index = 0; chunk_index < num_chunks; ++chunk_index) { |
+ g_crash_keys_whitelist.insert(base::StringPrintf( |
+ kChunkFormatString, keys[key_index].key_name, chunk_index + 1)); |
+ } |
+ } |
+ } |
+ LOG(ERROR) << "in SetupCrashKeysWhiteList, whitelist length: " |
+ << g_crash_keys_whitelist.size(); |
+ for (auto it = g_crash_keys_whitelist.begin(); |
+ it != g_crash_keys_whitelist.end(); it++) { |
+ LOG(ERROR) << "in SetupCrashKeysWhiteList, entry: " << *it; |
+ } |
+} |
+ |
+bool IsInWhiteList(const base::StringPiece& key) { |
+ // 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
|
+ return g_crash_keys_whitelist.find(key.as_string()) != |
+ g_crash_keys_whitelist.end(); |
+} |
+ |
void SetCrashKeyValue(const base::StringPiece& key, |
const base::StringPiece& value) { |
- g_crash_keys->SetKeyValue(key.data(), value.data()); |
+ LOG(ERROR) << "in SetCrashKeyValue for key " << key.data(); |
+ // TODO if #DEFINED(USE_WHITELIST) --use-whitelist |
+ if (IsInWhiteList(key)) { |
+ LOG(ERROR) << "in SetCrashKeyValue for key " << key.data() |
+ << " it is in the whitelist :D"; |
+ g_crash_keys->SetKeyValue(key.data(), value.data()); |
+ } else { |
+ LOG(ERROR) << "in SetCrashKeyValue for key " << key.data() |
+ << ", not in the whitelist"; |
+ } |
} |
void ClearCrashKey(const base::StringPiece& key) { |
@@ -1112,6 +1166,9 @@ void ClearCrashKey(const base::StringPiece& key) { |
void InitCrashKeys() { |
g_crash_keys = new CrashKeyStorage; |
GetCrashReporterClient()->RegisterCrashKeys(); |
+ // TODO if #DEFINED(USE_WHITELIST) --use-whitelist |
+ SetupCrashKeysWhiteList(GetCrashReporterClient()->GetWhiteListedCrashKeys(), |
+ crash_keys::kChunkMaxLength); |
base::debug::SetCrashKeyReportingFunctions(&SetCrashKeyValue, &ClearCrashKey); |
} |