OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 <stddef.h> | 5 #include <stddef.h> |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/environment.h" | 9 #include "base/environment.h" |
| 10 #include "base/files/file.h" |
10 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
11 #include "base/files/scoped_temp_dir.h" | 12 #include "base/files/scoped_temp_dir.h" |
12 #include "base/i18n/case_conversion.h" | 13 #include "base/i18n/case_conversion.h" |
13 #include "base/macros.h" | 14 #include "base/macros.h" |
14 #include "base/path_service.h" | 15 #include "base/path_service.h" |
15 #include "base/scoped_native_library.h" | 16 #include "base/scoped_native_library.h" |
16 #include "base/strings/string16.h" | 17 #include "base/strings/string16.h" |
17 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
18 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
19 #include "base/test/test_reg_util_win.h" | 20 #include "base/test/test_reg_util_win.h" |
20 #include "base/win/registry.h" | 21 #include "base/win/registry.h" |
21 #include "chrome/common/chrome_version.h" | 22 #include "chrome/common/chrome_version.h" |
22 #include "chrome_elf/blacklist/blacklist.h" | 23 #include "chrome_elf/blacklist/blacklist.h" |
23 #include "chrome_elf/blacklist/test/blacklist_test_main_dll.h" | |
24 #include "chrome_elf/chrome_elf_constants.h" | 24 #include "chrome_elf/chrome_elf_constants.h" |
| 25 #include "chrome_elf/nt_registry/nt_registry.h" |
25 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
26 | 27 |
27 const wchar_t kTestDllName1[] = L"blacklist_test_dll_1.dll"; | 28 const wchar_t kTestDllName1[] = L"blacklist_test_dll_1.dll"; |
28 const wchar_t kTestDllName2[] = L"blacklist_test_dll_2.dll"; | 29 const wchar_t kTestDllName2[] = L"blacklist_test_dll_2.dll"; |
29 const wchar_t kTestDllName3[] = L"blacklist_test_dll_3.dll"; | 30 const wchar_t kTestDllName3[] = L"blacklist_test_dll_3.dll"; |
30 | 31 |
31 const wchar_t kDll2Beacon[] = L"{F70A0100-2889-4629-9B44-610FE5C73231}"; | 32 const wchar_t kDll2Beacon[] = L"{F70A0100-2889-4629-9B44-610FE5C73231}"; |
32 const wchar_t kDll3Beacon[] = L"{9E056AEC-169E-400c-B2D0-5A07E3ACE2EB}"; | 33 const wchar_t kDll3Beacon[] = L"{9E056AEC-169E-400c-B2D0-5A07E3ACE2EB}"; |
33 | 34 |
34 extern const wchar_t* kEnvVars[]; | 35 extern const wchar_t* kEnvVars[]; |
35 | 36 |
36 extern "C" { | 37 namespace { |
37 // When modifying the blacklist in the test process, use the exported test dll | 38 |
38 // functions on the test blacklist dll, not the ones linked into the test | 39 // Functions we need from blacklist_test_main_dll.dll |
39 // executable itself. | 40 typedef void (*TestDll_AddDllsFromRegistryToBlacklistFunction)(); |
40 __declspec(dllimport) void TestDll_AddDllsFromRegistryToBlacklist(); | 41 typedef bool (*TestDll_AddDllToBlacklistFunction)(const wchar_t* dll_name); |
41 __declspec(dllimport) bool TestDll_AddDllToBlacklist(const wchar_t* dll_name); | 42 typedef int (*TestDll_BlacklistSizeFunction)(); |
42 __declspec(dllimport) int TestDll_BlacklistSize(); | 43 typedef void (*TestDll_BlockedDllFunction)(size_t blocked_index); |
43 __declspec(dllimport) void TestDll_BlockedDll(size_t blocked_index); | 44 typedef int (*TestDll_GetBlacklistIndexFunction)(const wchar_t* dll_name); |
44 __declspec(dllimport) int TestDll_GetBlacklistIndex(const wchar_t* dll_name); | 45 typedef bool (*TestDll_IsBlacklistInitializedFunction)(); |
45 __declspec(dllimport) bool TestDll_IsBlacklistInitialized(); | 46 typedef bool (*TestDll_RemoveDllFromBlacklistFunction)(const wchar_t* dll_name); |
46 __declspec(dllimport) bool TestDll_RemoveDllFromBlacklist( | 47 typedef bool (*TestDll_SuccessfullyBlockedFunction)( |
47 const wchar_t* dll_name); | |
48 __declspec(dllimport) bool TestDll_SuccessfullyBlocked( | |
49 const wchar_t** blocked_dlls, | 48 const wchar_t** blocked_dlls, |
50 int* size); | 49 int* size); |
51 } | 50 typedef void (*InitTestDllFunction)(); |
52 | 51 |
53 namespace { | 52 TestDll_AddDllsFromRegistryToBlacklistFunction |
| 53 TestDll_AddDllsFromRegistryToBlacklist = nullptr; |
| 54 TestDll_AddDllToBlacklistFunction TestDll_AddDllToBlacklist = nullptr; |
| 55 TestDll_BlacklistSizeFunction TestDll_BlacklistSize = nullptr; |
| 56 TestDll_BlockedDllFunction TestDll_BlockedDll = nullptr; |
| 57 TestDll_GetBlacklistIndexFunction TestDll_GetBlacklistIndex = nullptr; |
| 58 TestDll_IsBlacklistInitializedFunction TestDll_IsBlacklistInitialized = nullptr; |
| 59 TestDll_RemoveDllFromBlacklistFunction TestDll_RemoveDllFromBlacklist = nullptr; |
| 60 TestDll_SuccessfullyBlockedFunction TestDll_SuccessfullyBlocked = nullptr; |
| 61 InitTestDllFunction InitTestDll = nullptr; |
54 | 62 |
55 struct TestData { | 63 struct TestData { |
56 const wchar_t* dll_name; | 64 const wchar_t* dll_name; |
57 const wchar_t* dll_beacon; | 65 const wchar_t* dll_beacon; |
58 } test_data[] = { | 66 } test_data[] = { |
59 {kTestDllName2, kDll2Beacon}, | 67 {kTestDllName2, kDll2Beacon}, |
60 {kTestDllName3, kDll3Beacon} | 68 {kTestDllName3, kDll3Beacon} |
61 }; | 69 }; |
62 | 70 |
63 class BlacklistTest : public testing::Test { | 71 class BlacklistTest : public testing::Test { |
64 protected: | 72 protected: |
65 BlacklistTest() : override_manager_(), num_initially_blocked_(0) { | 73 BlacklistTest() : override_manager_(), num_initially_blocked_(0) { |
66 override_manager_.OverrideRegistry(HKEY_CURRENT_USER); | |
67 } | 74 } |
68 | 75 |
69 void CheckBlacklistedDllsNotLoaded() { | 76 void CheckBlacklistedDllsNotLoaded() { |
70 base::FilePath current_dir; | 77 base::FilePath current_dir; |
71 ASSERT_TRUE(PathService::Get(base::DIR_EXE, ¤t_dir)); | 78 ASSERT_TRUE(PathService::Get(base::DIR_EXE, ¤t_dir)); |
72 | 79 |
73 for (size_t i = 0; i < arraysize(test_data); ++i) { | 80 for (size_t i = 0; i < arraysize(test_data); ++i) { |
74 // Ensure that the dll has not been loaded both by inspecting the handle | 81 // Ensure that the dll has not been loaded both by inspecting the handle |
75 // returned by LoadLibrary and by looking for an environment variable that | 82 // returned by LoadLibrary and by looking for an environment variable that |
76 // is set when the DLL's entry point is called. | 83 // is set when the DLL's entry point is called. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 } | 125 } |
119 } | 126 } |
120 | 127 |
121 std::unique_ptr<base::win::RegKey> blacklist_registry_key_; | 128 std::unique_ptr<base::win::RegKey> blacklist_registry_key_; |
122 registry_util::RegistryOverrideManager override_manager_; | 129 registry_util::RegistryOverrideManager override_manager_; |
123 | 130 |
124 // The number of dlls initially blocked by the blacklist. | 131 // The number of dlls initially blocked by the blacklist. |
125 int num_initially_blocked_; | 132 int num_initially_blocked_; |
126 | 133 |
127 private: | 134 private: |
| 135 // This function puts registry-key redirection paths into |
| 136 // process-specific environment variables, for our test DLLs to access. |
| 137 // This will only work as long as the IPC is within the same process. |
| 138 void IpcOverrides() { |
| 139 if (!nt::HKCU_override.empty()) { |
| 140 ASSERT_TRUE(::SetEnvironmentVariableW(L"hkcu_override", |
| 141 nt::HKCU_override.c_str())); |
| 142 } |
| 143 if (!nt::HKLM_override.empty()) { |
| 144 ASSERT_TRUE(::SetEnvironmentVariableW(L"hklm_override", |
| 145 nt::HKLM_override.c_str())); |
| 146 } |
| 147 } |
| 148 |
128 void SetUp() override { | 149 void SetUp() override { |
129 // Force an import from blacklist_test_main_dll. | 150 override_manager_.OverrideRegistry(HKEY_CURRENT_USER, &nt::HKCU_override); |
130 InitBlacklistTestDll(); | 151 |
| 152 // Make the override path available to our test DLL. |
| 153 IpcOverrides(); |
| 154 |
| 155 // Load the main test Dll now. |
| 156 // Note: this has to happen after we set up the registry overrides. |
| 157 HMODULE dll = nullptr; |
| 158 dll = ::LoadLibraryW(L"blacklist_test_main_dll.dll"); |
| 159 if (!dll) |
| 160 return; |
| 161 TestDll_AddDllsFromRegistryToBlacklist = |
| 162 reinterpret_cast<TestDll_AddDllsFromRegistryToBlacklistFunction>( |
| 163 ::GetProcAddress(dll, "TestDll_AddDllsFromRegistryToBlacklist")); |
| 164 TestDll_AddDllToBlacklist = |
| 165 reinterpret_cast<TestDll_AddDllToBlacklistFunction>( |
| 166 ::GetProcAddress(dll, "TestDll_AddDllToBlacklist")); |
| 167 TestDll_BlacklistSize = reinterpret_cast<TestDll_BlacklistSizeFunction>( |
| 168 ::GetProcAddress(dll, "TestDll_BlacklistSize")); |
| 169 TestDll_BlockedDll = reinterpret_cast<TestDll_BlockedDllFunction>( |
| 170 ::GetProcAddress(dll, "TestDll_BlockedDll")); |
| 171 TestDll_GetBlacklistIndex = |
| 172 reinterpret_cast<TestDll_GetBlacklistIndexFunction>( |
| 173 ::GetProcAddress(dll, "TestDll_GetBlacklistIndex")); |
| 174 TestDll_IsBlacklistInitialized = |
| 175 reinterpret_cast<TestDll_IsBlacklistInitializedFunction>( |
| 176 ::GetProcAddress(dll, "TestDll_IsBlacklistInitialized")); |
| 177 TestDll_RemoveDllFromBlacklist = |
| 178 reinterpret_cast<TestDll_RemoveDllFromBlacklistFunction>( |
| 179 ::GetProcAddress(dll, "TestDll_RemoveDllFromBlacklist")); |
| 180 TestDll_SuccessfullyBlocked = |
| 181 reinterpret_cast<TestDll_SuccessfullyBlockedFunction>( |
| 182 ::GetProcAddress(dll, "TestDll_SuccessfullyBlocked")); |
| 183 InitTestDll = reinterpret_cast<InitTestDllFunction>( |
| 184 ::GetProcAddress(dll, "InitTestDll")); |
| 185 if (!TestDll_AddDllsFromRegistryToBlacklist || !TestDll_AddDllToBlacklist || |
| 186 !TestDll_BlacklistSize || !TestDll_BlockedDll || |
| 187 !TestDll_GetBlacklistIndex || !TestDll_IsBlacklistInitialized || |
| 188 !TestDll_RemoveDllFromBlacklist || !TestDll_SuccessfullyBlocked || |
| 189 !InitTestDll) |
| 190 return; |
| 191 |
| 192 // We have to call this exported function every time this test setup runs. |
| 193 // If the tests are running in single process mode, the test DLL does not |
| 194 // get reloaded everytime - but we need to make sure it updates |
| 195 // appropriately. |
| 196 InitTestDll(); |
| 197 |
131 blacklist_registry_key_.reset( | 198 blacklist_registry_key_.reset( |
132 new base::win::RegKey(HKEY_CURRENT_USER, | 199 new base::win::RegKey(HKEY_CURRENT_USER, |
133 blacklist::kRegistryBeaconPath, | 200 blacklist::kRegistryBeaconPath, |
134 KEY_QUERY_VALUE | KEY_SET_VALUE)); | 201 KEY_QUERY_VALUE | KEY_SET_VALUE)); |
135 | 202 |
136 // Find out how many dlls were blocked before the test starts. | 203 // Find out how many dlls were blocked before the test starts. |
137 TestDll_SuccessfullyBlocked(NULL, &num_initially_blocked_); | 204 TestDll_SuccessfullyBlocked(NULL, &num_initially_blocked_); |
138 } | 205 } |
139 | 206 |
140 void TearDown() override { | 207 void TearDown() override { |
141 TestDll_RemoveDllFromBlacklist(kTestDllName1); | 208 TestDll_RemoveDllFromBlacklist(kTestDllName1); |
142 TestDll_RemoveDllFromBlacklist(kTestDllName2); | 209 TestDll_RemoveDllFromBlacklist(kTestDllName2); |
143 TestDll_RemoveDllFromBlacklist(kTestDllName3); | 210 TestDll_RemoveDllFromBlacklist(kTestDllName3); |
144 } | 211 } |
| 212 |
| 213 // A scoped temporary directory to be destroyed with this test. |
| 214 base::ScopedTempDir reg_override_dir_; |
145 }; | 215 }; |
146 | 216 |
147 TEST_F(BlacklistTest, Beacon) { | 217 TEST_F(BlacklistTest, Beacon) { |
148 // Ensure that the beacon state starts off 'running' for this version. | 218 // Ensure that the beacon state starts off 'running' for this version. |
149 LONG result = blacklist_registry_key_->WriteValue( | 219 LONG result = blacklist_registry_key_->WriteValue( |
150 blacklist::kBeaconState, blacklist::BLACKLIST_SETUP_RUNNING); | 220 blacklist::kBeaconState, blacklist::BLACKLIST_SETUP_RUNNING); |
151 EXPECT_EQ(ERROR_SUCCESS, result); | 221 EXPECT_EQ(ERROR_SUCCESS, result); |
152 | 222 |
153 result = blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion, | 223 result = blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion, |
154 TEXT(CHROME_VERSION_STRING)); | 224 TEXT(CHROME_VERSION_STRING)); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 TEST_F(BlacklistTest, AddDllsFromRegistryToBlacklist) { | 317 TEST_F(BlacklistTest, AddDllsFromRegistryToBlacklist) { |
248 // Ensure that the blacklist is loaded. | 318 // Ensure that the blacklist is loaded. |
249 ASSERT_TRUE(TestDll_IsBlacklistInitialized()); | 319 ASSERT_TRUE(TestDll_IsBlacklistInitialized()); |
250 | 320 |
251 // Delete the finch registry key to clear its values. | 321 // Delete the finch registry key to clear its values. |
252 base::win::RegKey key(HKEY_CURRENT_USER, | 322 base::win::RegKey key(HKEY_CURRENT_USER, |
253 blacklist::kRegistryFinchListPath, | 323 blacklist::kRegistryFinchListPath, |
254 KEY_QUERY_VALUE | KEY_SET_VALUE); | 324 KEY_QUERY_VALUE | KEY_SET_VALUE); |
255 key.DeleteKey(L""); | 325 key.DeleteKey(L""); |
256 | 326 |
257 // Add the test dlls to the registry (with their name as both key and value). | 327 // Add the test dlls to the registry. |
| 328 // (REG_MULTI_SZ: eos separated, double null terminated.) |
258 base::win::RegKey finch_blacklist_registry_key( | 329 base::win::RegKey finch_blacklist_registry_key( |
259 HKEY_CURRENT_USER, | 330 HKEY_CURRENT_USER, |
260 blacklist::kRegistryFinchListPath, | 331 blacklist::kRegistryFinchListPath, |
261 KEY_QUERY_VALUE | KEY_SET_VALUE); | 332 KEY_QUERY_VALUE | KEY_SET_VALUE); |
| 333 |
| 334 std::vector<wchar_t>(reg_buffer); |
262 for (size_t i = 0; i < arraysize(test_data); ++i) { | 335 for (size_t i = 0; i < arraysize(test_data); ++i) { |
263 finch_blacklist_registry_key.WriteValue(test_data[i].dll_name, | 336 if (reg_buffer.size() > 0) |
264 test_data[i].dll_name); | 337 reg_buffer.push_back(L'\0'); |
| 338 const wchar_t* dll = test_data[i].dll_name; |
| 339 // Append the name, not including terminator. |
| 340 reg_buffer.insert(reg_buffer.end(), dll, dll + ::wcslen(dll)); |
265 } | 341 } |
| 342 reg_buffer.push_back(L'\0'); |
| 343 reg_buffer.push_back(L'\0'); |
| 344 |
| 345 finch_blacklist_registry_key.WriteValue( |
| 346 blacklist::kRegistryFinchListValueName, reg_buffer.data(), |
| 347 (DWORD)(reg_buffer.size() * sizeof(wchar_t)), REG_MULTI_SZ); |
266 | 348 |
267 TestDll_AddDllsFromRegistryToBlacklist(); | 349 TestDll_AddDllsFromRegistryToBlacklist(); |
268 CheckBlacklistedDllsNotLoaded(); | 350 CheckBlacklistedDllsNotLoaded(); |
269 } | 351 } |
270 | 352 |
271 void TestResetBeacon(std::unique_ptr<base::win::RegKey>& key, | 353 void TestResetBeacon(std::unique_ptr<base::win::RegKey>& key, |
272 DWORD input_state, | 354 DWORD input_state, |
273 DWORD expected_output_state) { | 355 DWORD expected_output_state) { |
274 LONG result = key->WriteValue(blacklist::kBeaconState, input_state); | 356 LONG result = key->WriteValue(blacklist::kBeaconState, input_state); |
275 EXPECT_EQ(ERROR_SUCCESS, result); | 357 EXPECT_EQ(ERROR_SUCCESS, result); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 &blacklist_state); | 423 &blacklist_state); |
342 EXPECT_EQ(blacklist_state, blacklist::BLACKLIST_SETUP_RUNNING); | 424 EXPECT_EQ(blacklist_state, blacklist::BLACKLIST_SETUP_RUNNING); |
343 | 425 |
344 DWORD attempt_count = blacklist::kBeaconMaxAttempts; | 426 DWORD attempt_count = blacklist::kBeaconMaxAttempts; |
345 blacklist_registry_key_->ReadValueDW(blacklist::kBeaconAttemptCount, | 427 blacklist_registry_key_->ReadValueDW(blacklist::kBeaconAttemptCount, |
346 &attempt_count); | 428 &attempt_count); |
347 EXPECT_EQ(static_cast<DWORD>(0), attempt_count); | 429 EXPECT_EQ(static_cast<DWORD>(0), attempt_count); |
348 } | 430 } |
349 | 431 |
350 } // namespace | 432 } // namespace |
OLD | NEW |