unload_dll_test.cc 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Copyright (c) 2012 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. #include "base/win/scoped_handle.h"
  5. #include "build/build_config.h"
  6. #include "sandbox/win/src/sandbox.h"
  7. #include "sandbox/win/src/sandbox_factory.h"
  8. #include "sandbox/win/src/target_services.h"
  9. #include "sandbox/win/tests/common/controller.h"
  10. #include "testing/gtest/include/gtest/gtest.h"
  11. namespace sandbox {
  12. // Loads and or unloads a DLL passed in the second parameter of argv.
  13. // The first parameter of argv is 'L' = load, 'U' = unload or 'B' for both.
  14. SBOX_TESTS_COMMAND int UseOneDLL(int argc, wchar_t** argv) {
  15. if (argc != 2)
  16. return SBOX_TEST_FAILED_TO_RUN_TEST;
  17. int rv = SBOX_TEST_FAILED_TO_RUN_TEST;
  18. wchar_t option = (argv[0])[0];
  19. if ((option == L'L') || (option == L'B')) {
  20. HMODULE module1 = ::LoadLibraryW(argv[1]);
  21. rv = (!module1) ? SBOX_TEST_FAILED : SBOX_TEST_SUCCEEDED;
  22. }
  23. if ((option == L'U') || (option == L'B')) {
  24. HMODULE module2 = ::GetModuleHandleW(argv[1]);
  25. rv = ::FreeLibrary(module2) ? SBOX_TEST_SUCCEEDED : SBOX_TEST_FAILED;
  26. }
  27. return rv;
  28. }
  29. // Opens the current executable's path.
  30. SBOX_TESTS_COMMAND int OpenExecutablePath(int argc, wchar_t** argv) {
  31. WCHAR full_path[MAX_PATH];
  32. if (!::GetModuleFileName(nullptr, full_path, MAX_PATH))
  33. return SBOX_TEST_FIRST_ERROR;
  34. if (::GetFileAttributes(full_path) == INVALID_FILE_ATTRIBUTES)
  35. return SBOX_TEST_FAILED;
  36. return SBOX_TEST_SUCCEEDED;
  37. }
  38. std::unique_ptr<TestRunner> BaselineAvicapRunner() {
  39. auto runner = std::make_unique<TestRunner>();
  40. runner->SetTestState(BEFORE_REVERT);
  41. runner->SetTimeout(2000);
  42. // Add a registry rule, because that ensures that the interception agent has
  43. // more than one item in its internal table.
  44. runner->AddRule(SubSystem::kFiles, Semantics::kFilesAllowQuery,
  45. L"\\??\\*.exe");
  46. return runner;
  47. }
  48. // Fails on Windows ARM64: https://crbug.com/905526
  49. #if defined(ARCH_CPU_ARM64)
  50. #define MAYBE_BaselineAvicapDll DISABLED_BaselineAvicapDll
  51. #else
  52. #define MAYBE_BaselineAvicapDll BaselineAvicapDll
  53. #endif
  54. TEST(UnloadDllTest, MAYBE_BaselineAvicapDll) {
  55. auto runner = BaselineAvicapRunner();
  56. // Note for the puzzled: avicap32.dll is a 64-bit dll in 64-bit versions of
  57. // windows so this test and the others just work.
  58. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner->RunTest(L"UseOneDLL L avicap32.dll"));
  59. runner = BaselineAvicapRunner();
  60. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner->RunTest(L"UseOneDLL B avicap32.dll"));
  61. }
  62. std::unique_ptr<TestRunner> UnloadAvicapNoPatchingRunner() {
  63. auto runner = std::make_unique<TestRunner>();
  64. runner->SetTestState(BEFORE_REVERT);
  65. runner->SetTimeout(2000);
  66. runner->GetPolicy()->GetConfig()->AddDllToUnload(L"avicap32.dll");
  67. return runner;
  68. }
  69. TEST(UnloadDllTest, UnloadAviCapDllNoPatching) {
  70. auto runner = UnloadAvicapNoPatchingRunner();
  71. EXPECT_EQ(SBOX_TEST_FAILED, runner->RunTest(L"UseOneDLL L avicap32.dll"));
  72. runner = UnloadAvicapNoPatchingRunner();
  73. EXPECT_EQ(SBOX_TEST_FAILED, runner->RunTest(L"UseOneDLL B avicap32.dll"));
  74. }
  75. std::unique_ptr<TestRunner> UnloadAvicapWithPatchingRunner() {
  76. auto runner = std::make_unique<TestRunner>();
  77. runner->SetTestState(BEFORE_REVERT);
  78. runner->SetTimeout(2000);
  79. runner->GetPolicy()->GetConfig()->AddDllToUnload(L"avicap32.dll");
  80. // Add a couple of rules that ensures that the interception agent add EAT
  81. // patching on the client which makes sure that the unload dll record does
  82. // not interact badly with them.
  83. runner->AddRule(SubSystem::kFiles, Semantics::kFilesAllowQuery,
  84. L"\\??\\*.exe");
  85. runner->AddRule(SubSystem::kFiles, Semantics::kFilesAllowQuery,
  86. L"\\??\\*.log");
  87. return runner;
  88. }
  89. TEST(UnloadDllTest, UnloadAviCapDllWithPatching) {
  90. auto runner = UnloadAvicapWithPatchingRunner();
  91. EXPECT_EQ(SBOX_TEST_FAILED, runner->RunTest(L"UseOneDLL L avicap32.dll"));
  92. runner = UnloadAvicapWithPatchingRunner();
  93. runner->SetTestState(AFTER_REVERT);
  94. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner->RunTest(L"OpenExecutablePath"));
  95. }
  96. } // namespace sandbox