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 (::wcslen(nt::HKCU_override) != 0) { |
| 140 ASSERT_TRUE( |
| 141 ::SetEnvironmentVariableW(L"hkcu_override", nt::HKCU_override)); |
| 142 } |
| 143 if (::wcslen(nt::HKLM_override) != 0) { |
| 144 ASSERT_TRUE( |
| 145 ::SetEnvironmentVariableW(L"hklm_override", nt::HKLM_override)); |
| 146 } |
| 147 } |
| 148 |
128 void SetUp() override { | 149 void SetUp() override { |
129 // Force an import from blacklist_test_main_dll. | 150 base::string16 temp; |
130 InitBlacklistTestDll(); | 151 override_manager_.OverrideRegistry(HKEY_CURRENT_USER, &temp); |
| 152 ::wcsncpy(nt::HKCU_override, temp.c_str(), nt::g_kRegMaxPathLen - 1); |
| 153 |
| 154 // Make the override path available to our test DLL. |
| 155 IpcOverrides(); |
| 156 |
| 157 // Load the main test Dll now. |
| 158 // Note: this has to happen after we set up the registry overrides. |
| 159 HMODULE dll = nullptr; |
| 160 dll = ::LoadLibraryW(L"blacklist_test_main_dll.dll"); |
| 161 if (!dll) |
| 162 return; |
| 163 TestDll_AddDllsFromRegistryToBlacklist = |
| 164 reinterpret_cast<TestDll_AddDllsFromRegistryToBlacklistFunction>( |
| 165 ::GetProcAddress(dll, "TestDll_AddDllsFromRegistryToBlacklist")); |
| 166 TestDll_AddDllToBlacklist = |
| 167 reinterpret_cast<TestDll_AddDllToBlacklistFunction>( |
| 168 ::GetProcAddress(dll, "TestDll_AddDllToBlacklist")); |
| 169 TestDll_BlacklistSize = reinterpret_cast<TestDll_BlacklistSizeFunction>( |
| 170 ::GetProcAddress(dll, "TestDll_BlacklistSize")); |
| 171 TestDll_BlockedDll = reinterpret_cast<TestDll_BlockedDllFunction>( |
| 172 ::GetProcAddress(dll, "TestDll_BlockedDll")); |
| 173 TestDll_GetBlacklistIndex = |
| 174 reinterpret_cast<TestDll_GetBlacklistIndexFunction>( |
| 175 ::GetProcAddress(dll, "TestDll_GetBlacklistIndex")); |
| 176 TestDll_IsBlacklistInitialized = |
| 177 reinterpret_cast<TestDll_IsBlacklistInitializedFunction>( |
| 178 ::GetProcAddress(dll, "TestDll_IsBlacklistInitialized")); |
| 179 TestDll_RemoveDllFromBlacklist = |
| 180 reinterpret_cast<TestDll_RemoveDllFromBlacklistFunction>( |
| 181 ::GetProcAddress(dll, "TestDll_RemoveDllFromBlacklist")); |
| 182 TestDll_SuccessfullyBlocked = |
| 183 reinterpret_cast<TestDll_SuccessfullyBlockedFunction>( |
| 184 ::GetProcAddress(dll, "TestDll_SuccessfullyBlocked")); |
| 185 InitTestDll = reinterpret_cast<InitTestDllFunction>( |
| 186 ::GetProcAddress(dll, "InitTestDll")); |
| 187 if (!TestDll_AddDllsFromRegistryToBlacklist || !TestDll_AddDllToBlacklist || |
| 188 !TestDll_BlacklistSize || !TestDll_BlockedDll || |
| 189 !TestDll_GetBlacklistIndex || !TestDll_IsBlacklistInitialized || |
| 190 !TestDll_RemoveDllFromBlacklist || !TestDll_SuccessfullyBlocked || |
| 191 !InitTestDll) |
| 192 return; |
| 193 |
| 194 // We have to call this exported function every time this test setup runs. |
| 195 // If the tests are running in single process mode, the test DLL does not |
| 196 // get reloaded everytime - but we need to make sure it updates |
| 197 // appropriately. |
| 198 InitTestDll(); |
| 199 |
131 blacklist_registry_key_.reset( | 200 blacklist_registry_key_.reset( |
132 new base::win::RegKey(HKEY_CURRENT_USER, | 201 new base::win::RegKey(HKEY_CURRENT_USER, |
133 blacklist::kRegistryBeaconPath, | 202 blacklist::kRegistryBeaconPath, |
134 KEY_QUERY_VALUE | KEY_SET_VALUE)); | 203 KEY_QUERY_VALUE | KEY_SET_VALUE)); |
135 | 204 |
136 // Find out how many dlls were blocked before the test starts. | 205 // Find out how many dlls were blocked before the test starts. |
137 TestDll_SuccessfullyBlocked(NULL, &num_initially_blocked_); | 206 TestDll_SuccessfullyBlocked(NULL, &num_initially_blocked_); |
138 } | 207 } |
139 | 208 |
140 void TearDown() override { | 209 void TearDown() override { |
141 TestDll_RemoveDllFromBlacklist(kTestDllName1); | 210 TestDll_RemoveDllFromBlacklist(kTestDllName1); |
142 TestDll_RemoveDllFromBlacklist(kTestDllName2); | 211 TestDll_RemoveDllFromBlacklist(kTestDllName2); |
143 TestDll_RemoveDllFromBlacklist(kTestDllName3); | 212 TestDll_RemoveDllFromBlacklist(kTestDllName3); |
144 } | 213 } |
| 214 |
| 215 // A scoped temporary directory to be destroyed with this test. |
| 216 base::ScopedTempDir reg_override_dir_; |
145 }; | 217 }; |
146 | 218 |
147 TEST_F(BlacklistTest, Beacon) { | 219 TEST_F(BlacklistTest, Beacon) { |
148 // Ensure that the beacon state starts off 'running' for this version. | 220 // Ensure that the beacon state starts off 'running' for this version. |
149 LONG result = blacklist_registry_key_->WriteValue( | 221 LONG result = blacklist_registry_key_->WriteValue( |
150 blacklist::kBeaconState, blacklist::BLACKLIST_SETUP_RUNNING); | 222 blacklist::kBeaconState, blacklist::BLACKLIST_SETUP_RUNNING); |
151 EXPECT_EQ(ERROR_SUCCESS, result); | 223 EXPECT_EQ(ERROR_SUCCESS, result); |
152 | 224 |
153 result = blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion, | 225 result = blacklist_registry_key_->WriteValue(blacklist::kBeaconVersion, |
154 TEXT(CHROME_VERSION_STRING)); | 226 TEXT(CHROME_VERSION_STRING)); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 TEST_F(BlacklistTest, AddDllsFromRegistryToBlacklist) { | 319 TEST_F(BlacklistTest, AddDllsFromRegistryToBlacklist) { |
248 // Ensure that the blacklist is loaded. | 320 // Ensure that the blacklist is loaded. |
249 ASSERT_TRUE(TestDll_IsBlacklistInitialized()); | 321 ASSERT_TRUE(TestDll_IsBlacklistInitialized()); |
250 | 322 |
251 // Delete the finch registry key to clear its values. | 323 // Delete the finch registry key to clear its values. |
252 base::win::RegKey key(HKEY_CURRENT_USER, | 324 base::win::RegKey key(HKEY_CURRENT_USER, |
253 blacklist::kRegistryFinchListPath, | 325 blacklist::kRegistryFinchListPath, |
254 KEY_QUERY_VALUE | KEY_SET_VALUE); | 326 KEY_QUERY_VALUE | KEY_SET_VALUE); |
255 key.DeleteKey(L""); | 327 key.DeleteKey(L""); |
256 | 328 |
257 // Add the test dlls to the registry (with their name as both key and value). | 329 // Add the test dlls to the registry. |
| 330 // (REG_MULTI_SZ: eos separated, double null terminated.) |
258 base::win::RegKey finch_blacklist_registry_key( | 331 base::win::RegKey finch_blacklist_registry_key( |
259 HKEY_CURRENT_USER, | 332 HKEY_CURRENT_USER, |
260 blacklist::kRegistryFinchListPath, | 333 blacklist::kRegistryFinchListPath, |
261 KEY_QUERY_VALUE | KEY_SET_VALUE); | 334 KEY_QUERY_VALUE | KEY_SET_VALUE); |
| 335 |
| 336 std::vector<wchar_t>(reg_buffer); |
262 for (size_t i = 0; i < arraysize(test_data); ++i) { | 337 for (size_t i = 0; i < arraysize(test_data); ++i) { |
263 finch_blacklist_registry_key.WriteValue(test_data[i].dll_name, | 338 if (reg_buffer.size() > 0) |
264 test_data[i].dll_name); | 339 reg_buffer.push_back(L'\0'); |
| 340 const wchar_t* dll = test_data[i].dll_name; |
| 341 // Append the name, not including terminator. |
| 342 reg_buffer.insert(reg_buffer.end(), dll, dll + ::wcslen(dll)); |
265 } | 343 } |
| 344 reg_buffer.push_back(L'\0'); |
| 345 reg_buffer.push_back(L'\0'); |
| 346 |
| 347 finch_blacklist_registry_key.WriteValue( |
| 348 blacklist::kRegistryFinchListValueName, reg_buffer.data(), |
| 349 (DWORD)(reg_buffer.size() * sizeof(wchar_t)), REG_MULTI_SZ); |
266 | 350 |
267 TestDll_AddDllsFromRegistryToBlacklist(); | 351 TestDll_AddDllsFromRegistryToBlacklist(); |
268 CheckBlacklistedDllsNotLoaded(); | 352 CheckBlacklistedDllsNotLoaded(); |
269 } | 353 } |
270 | 354 |
271 void TestResetBeacon(std::unique_ptr<base::win::RegKey>& key, | 355 void TestResetBeacon(std::unique_ptr<base::win::RegKey>& key, |
272 DWORD input_state, | 356 DWORD input_state, |
273 DWORD expected_output_state) { | 357 DWORD expected_output_state) { |
274 LONG result = key->WriteValue(blacklist::kBeaconState, input_state); | 358 LONG result = key->WriteValue(blacklist::kBeaconState, input_state); |
275 EXPECT_EQ(ERROR_SUCCESS, result); | 359 EXPECT_EQ(ERROR_SUCCESS, result); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 &blacklist_state); | 425 &blacklist_state); |
342 EXPECT_EQ(blacklist_state, blacklist::BLACKLIST_SETUP_RUNNING); | 426 EXPECT_EQ(blacklist_state, blacklist::BLACKLIST_SETUP_RUNNING); |
343 | 427 |
344 DWORD attempt_count = blacklist::kBeaconMaxAttempts; | 428 DWORD attempt_count = blacklist::kBeaconMaxAttempts; |
345 blacklist_registry_key_->ReadValueDW(blacklist::kBeaconAttemptCount, | 429 blacklist_registry_key_->ReadValueDW(blacklist::kBeaconAttemptCount, |
346 &attempt_count); | 430 &attempt_count); |
347 EXPECT_EQ(static_cast<DWORD>(0), attempt_count); | 431 EXPECT_EQ(static_cast<DWORD>(0), attempt_count); |
348 } | 432 } |
349 | 433 |
350 } // namespace | 434 } // namespace |
OLD | NEW |