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

Side by Side Diff: chrome/browser/chrome_elf_init_win.cc

Issue 2098713003: Moved a bunch of win-specific files to the new win folder in chrome/browser (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 5 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
« no previous file with comments | « chrome/browser/chrome_elf_init_win.h ('k') | chrome/browser/chrome_process_finder_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include <stddef.h>
6
7 #include "base/bind.h"
8 #include "base/metrics/field_trial.h"
9 #include "base/metrics/histogram.h"
10 #include "base/metrics/sparse_histogram.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/win/registry.h"
13 #include "chrome/browser/chrome_elf_init_win.h"
14 #include "chrome/common/chrome_version.h"
15 #include "chrome_elf/blacklist/blacklist.h"
16 #include "chrome_elf/chrome_elf_constants.h"
17 #include "chrome_elf/dll_hash/dll_hash.h"
18 #include "components/variations/variations_associated_data.h"
19 #include "content/public/browser/browser_thread.h"
20
21 const char kBrowserBlacklistTrialName[] = "BrowserBlacklist";
22 const char kBrowserBlacklistTrialDisabledGroupName[] = "NoBlacklist";
23
24 namespace {
25
26 // How long to wait, in seconds, before reporting for the second (and last
27 // time), what dlls were blocked from the browser process.
28 const int kBlacklistReportingDelaySec = 600;
29
30 // This enum is used to define the buckets for an enumerated UMA histogram.
31 // Hence,
32 // (a) existing enumerated constants should never be deleted or reordered, and
33 // (b) new constants should only be appended in front of
34 // BLACKLIST_SETUP_EVENT_MAX.
35 enum BlacklistSetupEventType {
36 // The blacklist beacon has placed to enable the browser blacklisting.
37 BLACKLIST_SETUP_ENABLED = 0,
38
39 // The blacklist was successfully enabled.
40 BLACKLIST_SETUP_RAN_SUCCESSFULLY,
41
42 // The blacklist setup code failed to execute.
43 BLACKLIST_SETUP_FAILED,
44
45 // The blacklist thunk setup code failed. This is probably an indication
46 // that something else patched that code first.
47 BLACKLIST_THUNK_SETUP_FAILED,
48
49 // Deprecated. The blacklist interception code failed to execute.
50 BLACKLIST_INTERCEPTION_FAILED,
51
52 // The blacklist was disabled for this run (after it failed too many times).
53 BLACKLIST_SETUP_DISABLED,
54
55 // Always keep this at the end.
56 BLACKLIST_SETUP_EVENT_MAX,
57 };
58
59 void RecordBlacklistSetupEvent(BlacklistSetupEventType blacklist_setup_event) {
60 UMA_HISTOGRAM_ENUMERATION("Blacklist.Setup",
61 blacklist_setup_event,
62 BLACKLIST_SETUP_EVENT_MAX);
63 }
64
65 // Report which DLLs were prevented from being loaded.
66 void ReportSuccessfulBlocks() {
67 // Figure out how many dlls were blocked.
68 int num_blocked_dlls = 0;
69 blacklist::SuccessfullyBlocked(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 blacklist::SuccessfullyBlocked(&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 std::string dll_name_utf8;
81 base::WideToUTF8(blocked_dlls[i], wcslen(blocked_dlls[i]), &dll_name_utf8);
82 int uma_hash = DllNameToHash(dll_name_utf8);
83
84 UMA_HISTOGRAM_SPARSE_SLOWLY("Blacklist.Blocked", uma_hash);
85 }
86 }
87
88 } // namespace
89
90 void InitializeChromeElf() {
91 if (base::FieldTrialList::FindFullName(kBrowserBlacklistTrialName) ==
92 kBrowserBlacklistTrialDisabledGroupName) {
93 // Disable the blacklist for all future runs by removing the beacon.
94 base::win::RegKey blacklist_registry_key(HKEY_CURRENT_USER);
95 blacklist_registry_key.DeleteKey(blacklist::kRegistryBeaconPath);
96 } else {
97 AddFinchBlacklistToRegistry();
98 BrowserBlacklistBeaconSetup();
99 }
100
101 // Report all successful blacklist interceptions.
102 ReportSuccessfulBlocks();
103
104 // Schedule another task to report all successful interceptions later.
105 // This time delay should be long enough to catch any dlls that attempt to
106 // inject after Chrome has started up.
107 content::BrowserThread::PostDelayedTask(
108 content::BrowserThread::UI,
109 FROM_HERE,
110 base::Bind(&ReportSuccessfulBlocks),
111 base::TimeDelta::FromSeconds(kBlacklistReportingDelaySec));
112 }
113
114 // Note that running multiple chrome instances with distinct user data
115 // directories could lead to deletion (and/or replacement) of the finch
116 // blacklist registry data in one instance before the second has a chance to
117 // read those values.
118 void AddFinchBlacklistToRegistry() {
119 base::win::RegKey finch_blacklist_registry_key(
120 HKEY_CURRENT_USER, blacklist::kRegistryFinchListPath, KEY_SET_VALUE);
121
122 // No point in trying to continue if the registry key isn't valid.
123 if (!finch_blacklist_registry_key.Valid())
124 return;
125
126 // Delete and recreate the key to clear the registry.
127 finch_blacklist_registry_key.DeleteKey(L"");
128 finch_blacklist_registry_key.Create(
129 HKEY_CURRENT_USER, blacklist::kRegistryFinchListPath, KEY_SET_VALUE);
130
131 std::map<std::string, std::string> params;
132 variations::GetVariationParams(kBrowserBlacklistTrialName, &params);
133
134 for (std::map<std::string, std::string>::iterator it = params.begin();
135 it != params.end();
136 ++it) {
137 std::wstring name = base::UTF8ToWide(it->first);
138 std::wstring val = base::UTF8ToWide(it->second);
139
140 finch_blacklist_registry_key.WriteValue(name.c_str(), val.c_str());
141 }
142 }
143
144 void BrowserBlacklistBeaconSetup() {
145 base::win::RegKey blacklist_registry_key(HKEY_CURRENT_USER,
146 blacklist::kRegistryBeaconPath,
147 KEY_QUERY_VALUE | KEY_SET_VALUE);
148
149 // No point in trying to continue if the registry key isn't valid.
150 if (!blacklist_registry_key.Valid())
151 return;
152
153 // Record the results of the last blacklist setup.
154 DWORD blacklist_state = blacklist::BLACKLIST_STATE_MAX;
155 blacklist_registry_key.ReadValueDW(blacklist::kBeaconState, &blacklist_state);
156
157 if (blacklist_state == blacklist::BLACKLIST_ENABLED) {
158 // The blacklist setup didn't crash, so we report if it was enabled or not.
159 if (blacklist::IsBlacklistInitialized()) {
160 RecordBlacklistSetupEvent(BLACKLIST_SETUP_RAN_SUCCESSFULLY);
161 } else {
162 // The only way for the blacklist to be enabled, but not fully
163 // initialized is if the thunk setup failed. See blacklist.cc
164 // for more details.
165 RecordBlacklistSetupEvent(BLACKLIST_THUNK_SETUP_FAILED);
166 }
167
168 // Regardless of if the blacklist was fully enabled or not, report how many
169 // times we had to try to set it up.
170 DWORD attempt_count = 0;
171 blacklist_registry_key.ReadValueDW(blacklist::kBeaconAttemptCount,
172 &attempt_count);
173 UMA_HISTOGRAM_COUNTS_100("Blacklist.RetryAttempts.Success", attempt_count);
174 } else if (blacklist_state == blacklist::BLACKLIST_SETUP_FAILED) {
175 // We can set the state to disabled without checking that the maximum number
176 // of attempts was exceeded because blacklist.cc has already done this.
177 RecordBlacklistSetupEvent(BLACKLIST_SETUP_FAILED);
178 blacklist_registry_key.WriteValue(blacklist::kBeaconState,
179 blacklist::BLACKLIST_DISABLED);
180 } else if (blacklist_state == blacklist::BLACKLIST_DISABLED) {
181 RecordBlacklistSetupEvent(BLACKLIST_SETUP_DISABLED);
182 }
183
184 // Find the last recorded blacklist version.
185 base::string16 blacklist_version;
186 blacklist_registry_key.ReadValue(blacklist::kBeaconVersion,
187 &blacklist_version);
188
189 if (blacklist_version != TEXT(CHROME_VERSION_STRING)) {
190 // The blacklist hasn't been enabled for this version yet, so enable it
191 // and reset the failure count to zero.
192 LONG set_version = blacklist_registry_key.WriteValue(
193 blacklist::kBeaconVersion,
194 TEXT(CHROME_VERSION_STRING));
195
196 LONG set_state = blacklist_registry_key.WriteValue(
197 blacklist::kBeaconState,
198 blacklist::BLACKLIST_ENABLED);
199
200 blacklist_registry_key.WriteValue(blacklist::kBeaconAttemptCount,
201 static_cast<DWORD>(0));
202
203 // Only report the blacklist as getting setup when both registry writes
204 // succeed, since otherwise the blacklist wasn't properly setup.
205 if (set_version == ERROR_SUCCESS && set_state == ERROR_SUCCESS)
206 RecordBlacklistSetupEvent(BLACKLIST_SETUP_ENABLED);
207 }
208 }
OLDNEW
« no previous file with comments | « chrome/browser/chrome_elf_init_win.h ('k') | chrome/browser/chrome_process_finder_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698