| 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" | 5 #include "base/bind.h" |
| 6 #include "base/metrics/field_trial.h" | 6 #include "base/metrics/field_trial.h" |
| 7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
| 8 #include "base/metrics/sparse_histogram.h" | 8 #include "base/metrics/sparse_histogram.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "base/win/registry.h" | 10 #include "base/win/registry.h" |
| 11 #include "chrome/browser/chrome_elf_init_win.h" | 11 #include "chrome/browser/chrome_elf_init_win.h" |
| 12 #include "chrome_elf/blacklist/blacklist.h" | 12 #include "chrome_elf/blacklist/blacklist.h" |
| 13 #include "chrome_elf/chrome_elf_constants.h" | 13 #include "chrome_elf/chrome_elf_constants.h" |
| 14 #include "chrome_elf/dll_hash/dll_hash.h" | 14 #include "chrome_elf/dll_hash/dll_hash.h" |
| 15 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
| 16 #include "version.h" // NOLINT | 16 #include "version.h" // NOLINT |
| 17 | 17 |
| 18 const char kBrowserBlacklistTrialName[] = "BrowserBlacklist"; | 18 const char kBrowserBlacklistTrialName[] = "BrowserBlacklist"; |
| 19 const char kBrowserBlacklistTrialDisabledGroupName[] = "NoBlacklist"; | 19 const char kBrowserBlacklistTrialDisabledGroupName[] = "NoBlacklist"; |
| 20 | 20 |
| 21 const DWORD kBeaconAttempts = 2; |
| 22 |
| 21 namespace { | 23 namespace { |
| 22 | 24 |
| 23 // How long to wait, in seconds, before reporting for the second (and last | 25 // How long to wait, in seconds, before reporting for the second (and last |
| 24 // time), what dlls were blocked from the browser process. | 26 // time), what dlls were blocked from the browser process. |
| 25 const int kBlacklistReportingDelaySec = 600; | 27 const int kBlacklistReportingDelaySec = 600; |
| 26 | 28 |
| 27 // This enum is used to define the buckets for an enumerated UMA histogram. | 29 // This enum is used to define the buckets for an enumerated UMA histogram. |
| 28 // Hence, | 30 // Hence, |
| 29 // (a) existing enumerated constants should never be deleted or reordered, and | 31 // (a) existing enumerated constants should never be deleted or reordered, and |
| 30 // (b) new constants should only be appended in front of | 32 // (b) new constants should only be appended in front of |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 // Schedule another task to report all sucessful interceptions later. | 98 // Schedule another task to report all sucessful interceptions later. |
| 97 // This time delay should be long enough to catch any dlls that attempt to | 99 // This time delay should be long enough to catch any dlls that attempt to |
| 98 // inject after Chrome has started up. | 100 // inject after Chrome has started up. |
| 99 content::BrowserThread::PostDelayedTask( | 101 content::BrowserThread::PostDelayedTask( |
| 100 content::BrowserThread::UI, | 102 content::BrowserThread::UI, |
| 101 FROM_HERE, | 103 FROM_HERE, |
| 102 base::Bind(&ReportSuccessfulBlocks), | 104 base::Bind(&ReportSuccessfulBlocks), |
| 103 base::TimeDelta::FromSeconds(kBlacklistReportingDelaySec)); | 105 base::TimeDelta::FromSeconds(kBlacklistReportingDelaySec)); |
| 104 } | 106 } |
| 105 | 107 |
| 108 void GetBlacklistFailedCount(DWORD* failed_count) { |
| 109 base::win::RegKey key(HKEY_CURRENT_USER, |
| 110 blacklist::kRegistryBeaconPath, |
| 111 KEY_QUERY_VALUE | KEY_SET_VALUE); |
| 112 bool count_exists = key.HasValue(blacklist::kBeaconFailedCount); |
| 113 if (!count_exists) |
| 114 key.WriteValue(blacklist::kBeaconFailedCount, static_cast<DWORD>(0)); |
| 115 |
| 116 key.ReadValueDW(blacklist::kBeaconFailedCount, failed_count); |
| 117 } |
| 118 |
| 106 void BrowserBlacklistBeaconSetup() { | 119 void BrowserBlacklistBeaconSetup() { |
| 107 base::win::RegKey blacklist_registry_key(HKEY_CURRENT_USER, | 120 base::win::RegKey blacklist_registry_key(HKEY_CURRENT_USER, |
| 108 blacklist::kRegistryBeaconPath, | 121 blacklist::kRegistryBeaconPath, |
| 109 KEY_QUERY_VALUE | KEY_SET_VALUE); | 122 KEY_QUERY_VALUE | KEY_SET_VALUE); |
| 110 | 123 |
| 111 // No point in trying to continue if the registry key isn't valid. | 124 // No point in trying to continue if the registry key isn't valid. |
| 112 if (!blacklist_registry_key.Valid()) | 125 if (!blacklist_registry_key.Valid()) |
| 113 return; | 126 return; |
| 114 | 127 |
| 115 // Record the results of the last blacklist setup. | 128 // Record the results of the last blacklist setup. |
| 116 DWORD blacklist_state = blacklist::BLACKLIST_STATE_MAX; | 129 DWORD blacklist_state = blacklist::BLACKLIST_STATE_MAX; |
| 117 blacklist_registry_key.ReadValueDW(blacklist::kBeaconState, &blacklist_state); | 130 blacklist_registry_key.ReadValueDW(blacklist::kBeaconState, &blacklist_state); |
| 118 | 131 |
| 119 if (blacklist_state == blacklist::BLACKLIST_ENABLED) { | 132 if (blacklist_state == blacklist::BLACKLIST_ENABLED) { |
| 120 RecordBlacklistSetupEvent(BLACKLIST_SETUP_RAN_SUCCESSFULLY); | 133 RecordBlacklistSetupEvent(BLACKLIST_SETUP_RAN_SUCCESSFULLY); |
| 134 |
| 135 // The blacklist was enabled successfully so we record the event (along with |
| 136 // the number of failed previous attempts) and reset the failure count. |
| 137 DWORD failed_attempt_count = 0; |
| 138 GetBlacklistFailedCount(&failed_attempt_count); |
| 139 UMA_HISTOGRAM_COUNTS("Blacklist.RetryWorked", failed_attempt_count); |
| 140 |
| 141 blacklist_registry_key.WriteValue(blacklist::kBeaconFailedCount, |
| 142 static_cast<DWORD>(0)); |
| 143 |
| 121 } else { | 144 } else { |
| 122 switch (blacklist_state) { | 145 switch (blacklist_state) { |
| 123 case blacklist::BLACKLIST_SETUP_RUNNING: | 146 case blacklist::BLACKLIST_SETUP_RUNNING: |
| 124 RecordBlacklistSetupEvent(BLACKLIST_SETUP_FAILED); | 147 RecordBlacklistSetupEvent(BLACKLIST_SETUP_FAILED); |
| 125 break; | 148 break; |
| 126 case blacklist::BLACKLIST_THUNK_SETUP: | 149 case blacklist::BLACKLIST_THUNK_SETUP: |
| 127 RecordBlacklistSetupEvent(BLACKLIST_THUNK_SETUP_FAILED); | 150 RecordBlacklistSetupEvent(BLACKLIST_THUNK_SETUP_FAILED); |
| 128 break; | 151 break; |
| 129 case blacklist::BLACKLIST_INTERCEPTING: | 152 case blacklist::BLACKLIST_INTERCEPTING: |
| 130 RecordBlacklistSetupEvent(BLACKLIST_INTERCEPTION_FAILED); | 153 RecordBlacklistSetupEvent(BLACKLIST_INTERCEPTION_FAILED); |
| 131 break; | 154 break; |
| 132 } | 155 } |
| 133 | 156 |
| 134 // Since some part of the blacklist failed, mark it as disabled | 157 // Some part of the blacklist failed. If this has occured some minimum |
| 135 // for this version. | 158 // number of times in a row we give up, disable it, and record the |
| 159 // disabling event with UMA. |
| 136 if (blacklist_state != blacklist::BLACKLIST_DISABLED) { | 160 if (blacklist_state != blacklist::BLACKLIST_DISABLED) { |
| 137 blacklist_registry_key.WriteValue(blacklist::kBeaconState, | 161 DWORD failed_attempt_count = 0; |
| 138 blacklist::BLACKLIST_DISABLED); | 162 GetBlacklistFailedCount(&failed_attempt_count); |
| 163 failed_attempt_count = failed_attempt_count + 1; |
| 164 |
| 165 if (failed_attempt_count >= kBeaconAttempts) { |
| 166 blacklist_registry_key.WriteValue(blacklist::kBeaconState, |
| 167 blacklist::BLACKLIST_DISABLED); |
| 168 UMA_HISTOGRAM_COUNTS("Blacklist.Disabled", true); |
| 169 } else { |
| 170 blacklist_registry_key.WriteValue(blacklist::kBeaconFailedCount, |
| 171 failed_attempt_count); |
| 172 blacklist_registry_key.WriteValue(blacklist::kBeaconState, |
| 173 blacklist::BLACKLIST_ENABLED); |
| 174 } |
| 139 } | 175 } |
| 140 } | 176 } |
| 141 | 177 |
| 142 // Find the last recorded blacklist version. | 178 // Find the last recorded blacklist version. |
| 143 base::string16 blacklist_version; | 179 base::string16 blacklist_version; |
| 144 blacklist_registry_key.ReadValue(blacklist::kBeaconVersion, | 180 blacklist_registry_key.ReadValue(blacklist::kBeaconVersion, |
| 145 &blacklist_version); | 181 &blacklist_version); |
| 146 | 182 |
| 147 if (blacklist_version != TEXT(CHROME_VERSION_STRING)) { | 183 if (blacklist_version != TEXT(CHROME_VERSION_STRING)) { |
| 148 // The blacklist hasn't been enabled for this version yet, so enable it. | 184 // The blacklist hasn't been enabled for this version yet, so enable it |
| 185 // and reset the failure count to zero. |
| 149 LONG set_version = blacklist_registry_key.WriteValue( | 186 LONG set_version = blacklist_registry_key.WriteValue( |
| 150 blacklist::kBeaconVersion, | 187 blacklist::kBeaconVersion, |
| 151 TEXT(CHROME_VERSION_STRING)); | 188 TEXT(CHROME_VERSION_STRING)); |
| 152 | 189 |
| 153 LONG set_state = blacklist_registry_key.WriteValue( | 190 LONG set_state = blacklist_registry_key.WriteValue( |
| 154 blacklist::kBeaconState, | 191 blacklist::kBeaconState, |
| 155 blacklist::BLACKLIST_ENABLED); | 192 blacklist::BLACKLIST_ENABLED); |
| 156 | 193 |
| 194 blacklist_registry_key.WriteValue(blacklist::kBeaconFailedCount, |
| 195 static_cast<DWORD>(0)); |
| 196 |
| 157 // Only report the blacklist as getting setup when both registry writes | 197 // Only report the blacklist as getting setup when both registry writes |
| 158 // succeed, since otherwise the blacklist wasn't properly setup. | 198 // succeed, since otherwise the blacklist wasn't properly setup. |
| 159 if (set_version == ERROR_SUCCESS && set_state == ERROR_SUCCESS) | 199 if (set_version == ERROR_SUCCESS && set_state == ERROR_SUCCESS) |
| 160 RecordBlacklistSetupEvent(BLACKLIST_SETUP_ENABLED); | 200 RecordBlacklistSetupEvent(BLACKLIST_SETUP_ENABLED); |
| 161 } | 201 } |
| 162 } | 202 } |
| OLD | NEW |