OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #include "base/bind.h" | |
6 #include "base/md5.h" | |
5 #include "base/metrics/field_trial.h" | 7 #include "base/metrics/field_trial.h" |
6 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/metrics/sparse_histogram.h" | |
7 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
8 #include "base/win/registry.h" | 11 #include "base/win/registry.h" |
9 #include "chrome/browser/chrome_elf_init_win.h" | 12 #include "chrome/browser/chrome_elf_init_win.h" |
10 #include "chrome_elf/blacklist/blacklist.h" | 13 #include "chrome_elf/blacklist/blacklist.h" |
14 #include "content/public/browser/browser_thread.h" | |
11 #include "version.h" // NOLINT | 15 #include "version.h" // NOLINT |
12 | 16 |
13 namespace { | 17 namespace { |
14 | 18 |
15 const char kBrowserBlacklistTrialName[] = "BrowserBlacklist"; | 19 const char kBrowserBlacklistTrialName[] = "BrowserBlacklist"; |
16 const char kBrowserBlacklistTrialEnabledGroupName[] = "Enabled"; | 20 const char kBrowserBlacklistTrialEnabledGroupName[] = "Enabled"; |
17 | 21 |
22 // How long to wait, in seconds, before reporting for the second (and last | |
23 // time), what dlls were blocked from the browser process. | |
24 const int kBlacklistReportingDelaySec = 600; | |
25 | |
18 // This enum is used to define the buckets for an enumerated UMA histogram. | 26 // This enum is used to define the buckets for an enumerated UMA histogram. |
19 // Hence, | 27 // Hence, |
20 // (a) existing enumerated constants should never be deleted or reordered, and | 28 // (a) existing enumerated constants should never be deleted or reordered, and |
21 // (b) new constants should only be appended in front of | 29 // (b) new constants should only be appended in front of |
22 // BLACKLIST_SETUP_EVENT_MAX. | 30 // BLACKLIST_SETUP_EVENT_MAX. |
23 enum BlacklistSetupEventType { | 31 enum BlacklistSetupEventType { |
24 // The blacklist beacon has placed to enable the browser blacklisting. | 32 // The blacklist beacon has placed to enable the browser blacklisting. |
25 BLACKLIST_SETUP_ENABLED = 0, | 33 BLACKLIST_SETUP_ENABLED = 0, |
26 | 34 |
27 // The blacklist was successfully enabled. | 35 // The blacklist was successfully enabled. |
(...skipping 11 matching lines...) Expand all Loading... | |
39 // Always keep this at the end. | 47 // Always keep this at the end. |
40 BLACKLIST_SETUP_EVENT_MAX, | 48 BLACKLIST_SETUP_EVENT_MAX, |
41 }; | 49 }; |
42 | 50 |
43 void RecordBlacklistSetupEvent(BlacklistSetupEventType blacklist_setup_event) { | 51 void RecordBlacklistSetupEvent(BlacklistSetupEventType blacklist_setup_event) { |
44 UMA_HISTOGRAM_ENUMERATION("Blacklist.Setup", | 52 UMA_HISTOGRAM_ENUMERATION("Blacklist.Setup", |
45 blacklist_setup_event, | 53 blacklist_setup_event, |
46 BLACKLIST_SETUP_EVENT_MAX); | 54 BLACKLIST_SETUP_EVENT_MAX); |
47 } | 55 } |
48 | 56 |
57 // Report which DLLs were prevented from being loaded. | |
58 void ReportSuccessfulBlocks() { | |
59 typedef void (*SuccessfullyBlockedPtr)(const wchar_t**, int*); | |
60 SuccessfullyBlockedPtr successfully_blocked = | |
61 reinterpret_cast<SuccessfullyBlockedPtr>(GetProcAddress( | |
62 GetModuleHandle(L"chrome_elf.dll"), "SuccessfullyBlocked")); | |
63 | |
64 if (!successfully_blocked) | |
65 return; | |
66 | |
67 // Figure out how many dlls were blocked. | |
68 int num_blocked_dlls = 0; | |
69 successfully_blocked(NULL, &num_blocked_dlls); | |
70 | |
71 if (num_blocked_dlls == 0) | |
72 return; | |
73 | |
74 // Now retrieve the list of blocked dlls. | |
75 std::vector<const wchar_t*> blocked_dlls(num_blocked_dlls); | |
76 successfully_blocked(&blocked_dlls[0], &num_blocked_dlls); | |
77 | |
78 // Send up the hashes of the blocked dlls via UMA. | |
79 for (size_t i = 0; i < blocked_dlls.size(); ++i) { | |
80 base::MD5Digest hash; | |
csharp
2014/02/25 15:20:50
asvitkine@, any hints/tips on a better hash to use
Alexei Svitkine (slow)
2014/02/25 15:51:54
Another histogram uses this one, which is indeed c
| |
81 base::MD5Sum(blocked_dlls[i], wcslen(blocked_dlls[i]), &hash); | |
82 | |
83 // Convert the md5 hash to an integer. Strip off the signed bit because | |
84 // UMA doesn't support negative values, but takes a signed int as input. | |
85 uint32 uma_hash = | |
86 static_cast<int>(hash.a[0] + (hash.a[1] << 8) + (hash.a[2] << 12) + | |
87 ((hash.a[3] * 0x7f) << 16)); | |
88 | |
89 UMA_HISTOGRAM_SPARSE_SLOWLY("Blacklist.Blocked", uma_hash); | |
90 } | |
91 } | |
92 | |
49 } // namespace | 93 } // namespace |
50 | 94 |
51 void InitializeChromeElf() { | 95 void InitializeChromeElf() { |
52 if (base::FieldTrialList::FindFullName(kBrowserBlacklistTrialName) == | 96 if (base::FieldTrialList::FindFullName(kBrowserBlacklistTrialName) == |
53 kBrowserBlacklistTrialEnabledGroupName) { | 97 kBrowserBlacklistTrialEnabledGroupName) { |
54 BrowserBlacklistBeaconSetup(); | 98 BrowserBlacklistBeaconSetup(); |
55 } else { | 99 } else { |
56 // Disable the blacklist for all future runs by removing the beacon. | 100 // Disable the blacklist for all future runs by removing the beacon. |
57 base::win::RegKey blacklist_registry_key(HKEY_CURRENT_USER); | 101 base::win::RegKey blacklist_registry_key(HKEY_CURRENT_USER); |
58 blacklist_registry_key.DeleteKey(blacklist::kRegistryBeaconPath); | 102 blacklist_registry_key.DeleteKey(blacklist::kRegistryBeaconPath); |
59 } | 103 } |
104 | |
105 // Report all successful blacklist interceptions. | |
106 ReportSuccessfulBlocks(); | |
107 | |
108 // Schedule another task to report all sucessful interceptions later. | |
109 // This time delay should be long enough to catch any dlls that attempt to | |
110 // inject after Chrome has started up. | |
111 content::BrowserThread::PostDelayedTask( | |
112 content::BrowserThread::UI, | |
113 FROM_HERE, | |
114 base::Bind(&ReportSuccessfulBlocks), | |
115 base::TimeDelta::FromSeconds(kBlacklistReportingDelaySec)); | |
60 } | 116 } |
61 | 117 |
62 void BrowserBlacklistBeaconSetup() { | 118 void BrowserBlacklistBeaconSetup() { |
63 base::win::RegKey blacklist_registry_key(HKEY_CURRENT_USER, | 119 base::win::RegKey blacklist_registry_key(HKEY_CURRENT_USER, |
64 blacklist::kRegistryBeaconPath, | 120 blacklist::kRegistryBeaconPath, |
65 KEY_QUERY_VALUE | KEY_SET_VALUE); | 121 KEY_QUERY_VALUE | KEY_SET_VALUE); |
66 | 122 |
67 // Find the last recorded blacklist version. | 123 // Find the last recorded blacklist version. |
68 base::string16 blacklist_version; | 124 base::string16 blacklist_version; |
69 blacklist_registry_key.ReadValue(blacklist::kBeaconVersion, | 125 blacklist_registry_key.ReadValue(blacklist::kBeaconVersion, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
112 | 168 |
113 // Since some part of the blacklist failed, ensure it is now disabled | 169 // Since some part of the blacklist failed, ensure it is now disabled |
114 // for this version. | 170 // for this version. |
115 if (blacklist_state != blacklist::BLACKLIST_DISABLED) { | 171 if (blacklist_state != blacklist::BLACKLIST_DISABLED) { |
116 blacklist_registry_key.WriteValue(blacklist::kBeaconState, | 172 blacklist_registry_key.WriteValue(blacklist::kBeaconState, |
117 blacklist::BLACKLIST_DISABLED); | 173 blacklist::BLACKLIST_DISABLED); |
118 } | 174 } |
119 } | 175 } |
120 } | 176 } |
121 } | 177 } |
OLD | NEW |