signed_interception.cc 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // Copyright 2019 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 "sandbox/win/src/signed_interception.h"
  5. #include <stdint.h>
  6. #include "sandbox/win/src/crosscall_client.h"
  7. #include "sandbox/win/src/ipc_tags.h"
  8. #include "sandbox/win/src/policy_params.h"
  9. #include "sandbox/win/src/policy_target.h"
  10. #include "sandbox/win/src/sandbox_factory.h"
  11. #include "sandbox/win/src/sandbox_nt_util.h"
  12. #include "sandbox/win/src/sharedmem_ipc_client.h"
  13. #include "sandbox/win/src/target_services.h"
  14. namespace sandbox {
  15. NTSTATUS WINAPI
  16. TargetNtCreateSection(NtCreateSectionFunction orig_CreateSection,
  17. PHANDLE section_handle,
  18. ACCESS_MASK desired_access,
  19. POBJECT_ATTRIBUTES object_attributes,
  20. PLARGE_INTEGER maximum_size,
  21. ULONG section_page_protection,
  22. ULONG allocation_attributes,
  23. HANDLE file_handle) {
  24. do {
  25. // The section only needs to have SECTION_MAP_EXECUTE, but the permissions
  26. // vary depending on the OS. Windows 1903 and higher requests (SECTION_QUERY
  27. // | SECTION_MAP_READ | SECTION_MAP_EXECUTE) while previous OS versions also
  28. // request SECTION_MAP_WRITE. Just check for EXECUTE.
  29. if (!(desired_access & SECTION_MAP_EXECUTE))
  30. break;
  31. if (object_attributes)
  32. break;
  33. if (maximum_size)
  34. break;
  35. if (section_page_protection != PAGE_EXECUTE)
  36. break;
  37. if (allocation_attributes != SEC_IMAGE)
  38. break;
  39. // IPC must be fully started.
  40. void* memory = GetGlobalIPCMemory();
  41. if (!memory)
  42. break;
  43. std::unique_ptr<wchar_t, NtAllocDeleter> path;
  44. if (!NtGetPathFromHandle(file_handle, &path))
  45. break;
  46. const wchar_t* const_name = path.get();
  47. CountedParameterSet<NameBased> params;
  48. params[NameBased::NAME] = ParamPickerMake(const_name);
  49. // Check if this will be sent to the broker.
  50. if (!QueryBroker(IpcTag::NTCREATESECTION, params.GetBase()))
  51. break;
  52. if (!ValidParameter(section_handle, sizeof(HANDLE), WRITE))
  53. break;
  54. CrossCallReturn answer = {0};
  55. answer.nt_status = STATUS_INVALID_IMAGE_HASH;
  56. SharedMemIPCClient ipc(memory);
  57. ResultCode code =
  58. CrossCall(ipc, IpcTag::NTCREATESECTION, file_handle, &answer);
  59. if (code != SBOX_ALL_OK)
  60. break;
  61. if (!NT_SUCCESS(answer.nt_status))
  62. break;
  63. __try {
  64. *section_handle = answer.handle;
  65. return answer.nt_status;
  66. } __except (EXCEPTION_EXECUTE_HANDLER) {
  67. break;
  68. }
  69. } while (false);
  70. // Fall back to the original API in all failure cases.
  71. return orig_CreateSection(section_handle, desired_access, object_attributes,
  72. maximum_size, section_page_protection,
  73. allocation_attributes, file_handle);
  74. }
  75. } // namespace sandbox