chrome_elf_init_win.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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 "base/metrics/field_trial.h"
6#include "base/metrics/histogram.h"
7#include "base/strings/utf_string_conversions.h"
8#include "base/win/registry.h"
9#include "chrome/browser/chrome_elf_init_win.h"
10#include "chrome_elf/blacklist/blacklist.h"
11#include "version.h"  // NOLINT
12
13namespace {
14
15const char kBrowserBlacklistTrialName[] = "BrowserBlacklist";
16const char kBrowserBlacklistTrialEnabledGroupName[] = "Enabled";
17
18// This enum is used to define the buckets for an enumerated UMA histogram.
19// Hence,
20//   (a) existing enumerated constants should never be deleted or reordered, and
21//   (b) new constants should only be appended in front of
22//       BLACKLIST_SETUP_EVENT_MAX.
23enum BlacklistSetupEventType {
24  // The blacklist beacon has placed to enable the browser blacklisting.
25  BLACKLIST_SETUP_ENABLED = 0,
26
27  // The blacklist was successfully enabled.
28  BLACKLIST_SETUP_RAN_SUCCESSFULLY,
29
30  // The blacklist setup code failed to execute.
31  BLACKLIST_SETUP_FAILED,
32
33  // The blacklist thunk setup code failed to execute.
34  BLACKLIST_THUNK_SETUP_FAILED,
35
36  // The blacklist interception code failed to execute.
37  BLACKLIST_INTERCEPTION_FAILED,
38
39  // Always keep this at the end.
40  BLACKLIST_SETUP_EVENT_MAX,
41};
42
43void RecordBlacklistSetupEvent(BlacklistSetupEventType blacklist_setup_event) {
44  UMA_HISTOGRAM_ENUMERATION("Blacklist.Setup",
45                            blacklist_setup_event,
46                            BLACKLIST_SETUP_EVENT_MAX);
47}
48
49}  // namespace
50
51void InitializeChromeElf() {
52  if (base::FieldTrialList::FindFullName(kBrowserBlacklistTrialName) ==
53      kBrowserBlacklistTrialEnabledGroupName) {
54    BrowserBlacklistBeaconSetup();
55  } else {
56    // Disable the blacklist for all future runs by removing the beacon.
57    base::win::RegKey blacklist_registry_key(HKEY_CURRENT_USER);
58    blacklist_registry_key.DeleteKey(blacklist::kRegistryBeaconPath);
59  }
60}
61
62void BrowserBlacklistBeaconSetup() {
63  base::win::RegKey blacklist_registry_key(HKEY_CURRENT_USER,
64                                           blacklist::kRegistryBeaconPath,
65                                           KEY_QUERY_VALUE | KEY_SET_VALUE);
66
67  // Find the last recorded blacklist version.
68  base::string16 blacklist_version;
69  blacklist_registry_key.ReadValue(blacklist::kBeaconVersion,
70                                   &blacklist_version);
71
72  if (blacklist_version != TEXT(CHROME_VERSION_STRING)) {
73    // The blacklist hasn't run for this version yet, so enable it.
74    LONG set_version = blacklist_registry_key.WriteValue(
75        blacklist::kBeaconVersion,
76        TEXT(CHROME_VERSION_STRING));
77
78    LONG set_state = blacklist_registry_key.WriteValue(
79        blacklist::kBeaconState,
80        blacklist::BLACKLIST_ENABLED);
81
82    // Only report the blacklist as getting setup when both registry writes
83    // succeed, since otherwise the blacklist wasn't properly setup.
84    if (set_version == ERROR_SUCCESS && set_state == ERROR_SUCCESS)
85      RecordBlacklistSetupEvent(BLACKLIST_SETUP_ENABLED);
86
87    // Don't try to record if the blacklist setup succeeded or failed in the
88    // run since it could have been from either this version or the previous
89    // version (since crashes occur before we set the version in the registry).
90  } else {
91    // The blacklist version didn't change, so record the results of the
92    // latest setup.
93    DWORD blacklist_state = blacklist::BLACKLIST_STATE_MAX;
94    blacklist_registry_key.ReadValueDW(blacklist::kBeaconState,
95                                       &blacklist_state);
96
97    // Record the results of the latest blacklist setup.
98    if (blacklist_state == blacklist::BLACKLIST_ENABLED) {
99      RecordBlacklistSetupEvent(BLACKLIST_SETUP_RAN_SUCCESSFULLY);
100    } else {
101      switch (blacklist_state) {
102        case blacklist::BLACKLIST_SETUP_RUNNING:
103          RecordBlacklistSetupEvent(BLACKLIST_SETUP_FAILED);
104          break;
105        case blacklist::BLACKLIST_THUNK_SETUP:
106          RecordBlacklistSetupEvent(BLACKLIST_THUNK_SETUP_FAILED);
107          break;
108        case blacklist::BLACKLIST_INTERCEPTING:
109          RecordBlacklistSetupEvent(BLACKLIST_INTERCEPTION_FAILED);
110          break;
111      }
112
113      // Since some part of the blacklist failed, ensure it is now disabled
114      // for this version.
115      if (blacklist_state != blacklist::BLACKLIST_DISABLED) {
116        blacklist_registry_key.WriteValue(blacklist::kBeaconState,
117                                          blacklist::BLACKLIST_DISABLED);
118      }
119    }
120  }
121}
122