Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Unified Diff: sandbox/win/src/process_mitigations_test.cc

Issue 1856993003: Implement sandbox hooks to forward OPM related GDI system calls. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed header Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sandbox/win/src/policy_low_level.h ('k') | sandbox/win/src/process_mitigations_win32k_dispatcher.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sandbox/win/src/process_mitigations_test.cc
diff --git a/sandbox/win/src/process_mitigations_test.cc b/sandbox/win/src/process_mitigations_test.cc
index cac31fa0741e890a231f063a5753da07d9a6ef6e..97636bcd84dcb7b1227efc4d6f875282c294fc3c 100644
--- a/sandbox/win/src/process_mitigations_test.cc
+++ b/sandbox/win/src/process_mitigations_test.cc
@@ -2,15 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <initguid.h>
+#include <d3d9.h>
+#include <Opmapi.h>
+#include <windows.h>
+
+#include <map>
+#include <string>
+
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
+#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
#include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"
#include "sandbox/win/src/nt_internals.h"
#include "sandbox/win/src/process_mitigations.h"
+#include "sandbox/win/src/process_mitigations_win32k_policy.h"
#include "sandbox/win/src/sandbox.h"
#include "sandbox/win/src/sandbox_factory.h"
#include "sandbox/win/src/target_services.h"
@@ -199,6 +210,284 @@ void TestWin10ImageLoadLowLabel(bool is_success_test) {
runner.RunTest(test.c_str()));
}
+BOOL CALLBACK MonitorEnumCallback(HMONITOR monitor,
+ HDC hdc_monitor,
+ LPRECT rect_monitor,
+ LPARAM data) {
+ std::map<HMONITOR, base::string16>& monitors =
+ *reinterpret_cast<std::map<HMONITOR, base::string16>*>(data);
+ MONITORINFOEXW monitor_info = {};
+ monitor_info.cbSize = sizeof(monitor_info);
+
+ if (!::GetMonitorInfoW(monitor,
+ reinterpret_cast<MONITORINFO*>(&monitor_info)))
+ return FALSE;
+ monitors[monitor] = monitor_info.szDevice;
+ return TRUE;
+}
+
+std::map<HMONITOR, std::wstring> EnumerateMonitors() {
+ std::map<HMONITOR, std::wstring> result;
+ ::EnumDisplayMonitors(nullptr, nullptr, MonitorEnumCallback,
+ reinterpret_cast<LPARAM>(&result));
+ return result;
+}
+
+#define HMONITOR_ENTRY(monitor) \
+ result[reinterpret_cast<HMONITOR>(monitor)] = \
+ base::StringPrintf(L"\\\\.\\DISPLAY%X", monitor)
+
+std::map<HMONITOR, std::wstring> GetTestMonitors() {
+ std::map<HMONITOR, std::wstring> result;
+
+ HMONITOR_ENTRY(0x11111111);
+ HMONITOR_ENTRY(0x22222222);
+ HMONITOR_ENTRY(0x44444444);
+ HMONITOR_ENTRY(0x88888888);
+ return result;
+}
+
+std::wstring UnicodeStringToString(PUNICODE_STRING name) {
+ return std::wstring(name->Buffer,
+ name->Buffer + (name->Length / sizeof(name->Buffer[0])));
+}
+
+// Returns an index 1, 2, 4 or 8 depening on the device. 0 on error.
+DWORD GetTestDeviceMonitorIndex(PUNICODE_STRING device_name) {
+ std::wstring name = UnicodeStringToString(device_name);
+ std::map<HMONITOR, std::wstring> monitors = GetTestMonitors();
+ for (const auto& monitor : monitors) {
+ if (name == monitor.second)
+ return static_cast<DWORD>(reinterpret_cast<uintptr_t>(monitor.first)) &
+ 0xF;
+ }
+ return 0;
+}
+
+NTSTATUS WINAPI GetSuggestedOPMProtectedOutputArraySizeTest(
+ PUNICODE_STRING device_name,
+ DWORD* suggested_output_array_size) {
+ DWORD monitor = GetTestDeviceMonitorIndex(device_name);
+ if (!monitor)
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ *suggested_output_array_size = monitor;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS WINAPI
+CreateOPMProtectedOutputsTest(PUNICODE_STRING device_name,
+ DXGKMDT_OPM_VIDEO_OUTPUT_SEMANTICS vos,
+ DWORD output_array_size,
+ DWORD* num_in_output_array,
+ OPM_PROTECTED_OUTPUT_HANDLE* output_array) {
+ DWORD monitor = GetTestDeviceMonitorIndex(device_name);
+ if (!monitor)
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ if (vos != DXGKMDT_OPM_VOS_OPM_SEMANTICS)
+ return STATUS_INVALID_PARAMETER;
+ if (output_array_size != monitor)
+ return STATUS_INVALID_PARAMETER;
+ *num_in_output_array = monitor - 1;
+ for (DWORD index = 0; index < monitor - 1; ++index) {
+ output_array[index] =
+ reinterpret_cast<OPM_PROTECTED_OUTPUT_HANDLE>((monitor << 4) + index);
+ }
+ return STATUS_SUCCESS;
+}
+
+ULONG CalculateCertLength(ULONG monitor) {
+ return (monitor * 0x800) + 0xabc;
+}
+
+NTSTATUS WINAPI GetCertificateTest(PUNICODE_STRING device_name,
+ DXGKMDT_CERTIFICATE_TYPE certificate_type,
+ BYTE* certificate,
+ ULONG certificate_length) {
+ DWORD monitor = GetTestDeviceMonitorIndex(device_name);
+ if (!monitor)
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ if (certificate_type != DXGKMDT_OPM_CERTIFICATE)
+ return STATUS_INVALID_PARAMETER;
+ if (certificate_length != CalculateCertLength(monitor))
+ return STATUS_INVALID_PARAMETER;
+ memset(certificate, 'A' + monitor, certificate_length);
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS WINAPI
+GetCertificateSizeTest(PUNICODE_STRING device_name,
+ DXGKMDT_CERTIFICATE_TYPE certificate_type,
+ ULONG* certificate_length) {
+ DWORD monitor = GetTestDeviceMonitorIndex(device_name);
+ if (!monitor)
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ if (certificate_type != DXGKMDT_OPM_CERTIFICATE)
+ return STATUS_INVALID_PARAMETER;
+ *certificate_length = CalculateCertLength(monitor);
+ return STATUS_SUCCESS;
+}
+
+// Check for valid output handle and return the monitor index.
+DWORD IsValidProtectedOutput(OPM_PROTECTED_OUTPUT_HANDLE protected_output) {
+ uintptr_t handle = reinterpret_cast<uintptr_t>(protected_output);
+ uintptr_t monitor = handle >> 4;
+ uintptr_t index = handle & 0xF;
+ switch (monitor) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ break;
+ default:
+ return 0;
+ }
+ if (index >= (monitor - 1))
+ return 0;
+ return static_cast<DWORD>(monitor);
+}
+
+NTSTATUS WINAPI
+GetCertificateByHandleTest(OPM_PROTECTED_OUTPUT_HANDLE protected_output,
+ DXGKMDT_CERTIFICATE_TYPE certificate_type,
+ BYTE* certificate,
+ ULONG certificate_length) {
+ DWORD monitor = IsValidProtectedOutput(protected_output);
+ if (!monitor)
+ return STATUS_INVALID_HANDLE;
+ if (certificate_type != DXGKMDT_OPM_CERTIFICATE)
+ return STATUS_INVALID_PARAMETER;
+ if (certificate_length != CalculateCertLength(monitor))
+ return STATUS_INVALID_PARAMETER;
+ memset(certificate, 'A' + monitor, certificate_length);
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS WINAPI
+GetCertificateSizeByHandleTest(OPM_PROTECTED_OUTPUT_HANDLE protected_output,
+ DXGKMDT_CERTIFICATE_TYPE certificate_type,
+ ULONG* certificate_length) {
+ DWORD monitor = IsValidProtectedOutput(protected_output);
+ if (!monitor)
+ return STATUS_INVALID_HANDLE;
+ if (certificate_type != DXGKMDT_OPM_CERTIFICATE)
+ return STATUS_INVALID_PARAMETER;
+ *certificate_length = CalculateCertLength(monitor);
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS WINAPI
+DestroyOPMProtectedOutputTest(OPM_PROTECTED_OUTPUT_HANDLE protected_output) {
+ if (!IsValidProtectedOutput(protected_output))
+ return STATUS_INVALID_HANDLE;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS WINAPI ConfigureOPMProtectedOutputTest(
+ OPM_PROTECTED_OUTPUT_HANDLE protected_output,
+ const DXGKMDT_OPM_CONFIGURE_PARAMETERS* parameters,
+ ULONG additional_parameters_size,
+ const BYTE* additional_parameters) {
+ if (!IsValidProtectedOutput(protected_output))
+ return STATUS_INVALID_HANDLE;
+ if (additional_parameters && additional_parameters_size)
+ return STATUS_INVALID_PARAMETER;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS WINAPI GetOPMInformationTest(
+ OPM_PROTECTED_OUTPUT_HANDLE protected_output,
+ const DXGKMDT_OPM_GET_INFO_PARAMETERS* parameters,
+ DXGKMDT_OPM_REQUESTED_INFORMATION* requested_information) {
+ DWORD monitor = IsValidProtectedOutput(protected_output);
+ if (!monitor)
+ return STATUS_INVALID_HANDLE;
+ memset(requested_information, '0' + monitor,
+ sizeof(DXGKMDT_OPM_REQUESTED_INFORMATION));
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS WINAPI
+GetOPMRandomNumberTest(OPM_PROTECTED_OUTPUT_HANDLE protected_output,
+ DXGKMDT_OPM_RANDOM_NUMBER* random_number) {
+ DWORD monitor = IsValidProtectedOutput(protected_output);
+ if (!monitor)
+ return STATUS_INVALID_HANDLE;
+ memset(random_number->abRandomNumber, '!' + monitor,
+ sizeof(random_number->abRandomNumber));
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS WINAPI SetOPMSigningKeyAndSequenceNumbersTest(
+ OPM_PROTECTED_OUTPUT_HANDLE protected_output,
+ const DXGKMDT_OPM_ENCRYPTED_PARAMETERS* parameters) {
+ DWORD monitor = IsValidProtectedOutput(protected_output);
+ if (!monitor)
+ return STATUS_INVALID_HANDLE;
+ DXGKMDT_OPM_ENCRYPTED_PARAMETERS test_params = {};
+ memset(test_params.abEncryptedParameters, 'a' + monitor,
+ sizeof(test_params.abEncryptedParameters));
+ if (memcmp(test_params.abEncryptedParameters,
+ parameters->abEncryptedParameters,
+ sizeof(test_params.abEncryptedParameters)) != 0)
+ return STATUS_INVALID_PARAMETER;
+ return STATUS_SUCCESS;
+}
+
+BOOL WINAPI EnumDisplayMonitorsTest(HDC hdc,
+ LPCRECT clip_rect,
+ MONITORENUMPROC enum_function,
+ LPARAM data) {
+ RECT rc = {};
+ for (const auto& monitor : GetTestMonitors()) {
+ if (!enum_function(monitor.first, hdc, &rc, data))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL WINAPI GetMonitorInfoWTest(HMONITOR monitor, LPMONITORINFO monitor_info) {
+ std::map<HMONITOR, std::wstring> monitors = GetTestMonitors();
+ if (monitor_info->cbSize != sizeof(MONITORINFO) &&
+ monitor_info->cbSize != sizeof(MONITORINFOEXW))
+ return FALSE;
+ auto it = monitors.find(monitor);
+ if (it == monitors.end())
+ return FALSE;
+ if (monitor_info->cbSize == sizeof(MONITORINFOEXW)) {
+ MONITORINFOEXW* monitor_info_ex =
+ reinterpret_cast<MONITORINFOEXW*>(monitor_info);
+ size_t copy_size = (it->second.size() + 1) * sizeof(WCHAR);
+ if (copy_size > sizeof(monitor_info_ex->szDevice) - sizeof(WCHAR))
+ copy_size = sizeof(monitor_info_ex->szDevice) - sizeof(WCHAR);
+ memset(monitor_info_ex->szDevice, 0, sizeof(monitor_info_ex->szDevice));
+ memcpy(monitor_info_ex->szDevice, it->second.c_str(), copy_size);
+ }
+ return TRUE;
+}
+
+#define RETURN_TEST_FUNC(n) \
+ if (strcmp(name, #n) == 0) { \
+ return n##Test; \
+ }
+
+void* FunctionOverrideForTest(const char* name) {
+ RETURN_TEST_FUNC(GetSuggestedOPMProtectedOutputArraySize);
+ RETURN_TEST_FUNC(CreateOPMProtectedOutputs);
+ RETURN_TEST_FUNC(GetCertificate);
+ RETURN_TEST_FUNC(GetCertificateSize);
+ RETURN_TEST_FUNC(DestroyOPMProtectedOutput);
+ RETURN_TEST_FUNC(ConfigureOPMProtectedOutput);
+ RETURN_TEST_FUNC(GetOPMInformation);
+ RETURN_TEST_FUNC(GetOPMRandomNumber);
+ RETURN_TEST_FUNC(SetOPMSigningKeyAndSequenceNumbers);
+ RETURN_TEST_FUNC(EnumDisplayMonitors);
+ RETURN_TEST_FUNC(GetMonitorInfoW);
+ RETURN_TEST_FUNC(GetCertificateByHandle);
+ RETURN_TEST_FUNC(GetCertificateSizeByHandle);
+ NOTREACHED();
+ return nullptr;
+}
+
} // namespace
namespace sandbox {
@@ -379,6 +668,302 @@ SBOX_TESTS_COMMAND int CheckWin8Lockdown(int argc, wchar_t **argv) {
return SBOX_TEST_SUCCEEDED;
}
+SBOX_TESTS_COMMAND int CheckWin8MonitorsRedirection(int argc, wchar_t** argv) {
+ std::map<HMONITOR, base::string16> monitors = EnumerateMonitors();
+ std::map<HMONITOR, base::string16> monitors_to_test = GetTestMonitors();
+ if (monitors.size() != monitors_to_test.size())
+ return SBOX_TEST_FIRST_ERROR;
+
+ for (const auto& monitor : monitors) {
+ auto result = monitors_to_test.find(monitor.first);
+ if (result == monitors_to_test.end())
+ return SBOX_TEST_SECOND_ERROR;
+ if (result->second != monitor.second)
+ return SBOX_TEST_THIRD_ERROR;
+ }
+ return SBOX_TEST_SUCCEEDED;
+}
+
+SBOX_TESTS_COMMAND int CheckWin8MonitorInfo(int argc, wchar_t** argv) {
+ std::map<HMONITOR, base::string16> monitors_to_test = GetTestMonitors();
+ MONITORINFO monitor_info = {};
+ MONITORINFOEXW monitor_info_exw = {};
+ MONITORINFOEXA monitor_info_exa = {};
+ HMONITOR valid_monitor = monitors_to_test.begin()->first;
+ std::wstring valid_device = monitors_to_test.begin()->second;
+ monitor_info.cbSize = sizeof(MONITORINFO);
+ if (!::GetMonitorInfoW(valid_monitor, &monitor_info))
+ return SBOX_TEST_FIRST_ERROR;
+ monitor_info.cbSize = sizeof(MONITORINFO);
+ if (!::GetMonitorInfoA(valid_monitor, &monitor_info))
+ return SBOX_TEST_SECOND_ERROR;
+ monitor_info_exw.cbSize = sizeof(MONITORINFOEXW);
+ if (!::GetMonitorInfoW(valid_monitor,
+ reinterpret_cast<MONITORINFO*>(&monitor_info_exw)) ||
+ valid_device != monitor_info_exw.szDevice) {
+ return SBOX_TEST_THIRD_ERROR;
+ }
+ monitor_info_exa.cbSize = sizeof(MONITORINFOEXA);
+ if (!::GetMonitorInfoA(valid_monitor,
+ reinterpret_cast<MONITORINFO*>(&monitor_info_exa)) ||
+ valid_device != base::ASCIIToUTF16(monitor_info_exa.szDevice)) {
+ return SBOX_TEST_FOURTH_ERROR;
+ }
+
+ // Invalid size checks.
+ monitor_info.cbSize = 0;
+ if (::GetMonitorInfoW(valid_monitor, &monitor_info))
+ return SBOX_TEST_FIFTH_ERROR;
+ monitor_info.cbSize = 0x10000;
+ if (::GetMonitorInfoW(valid_monitor, &monitor_info))
+ return SBOX_TEST_SIXTH_ERROR;
+
+ // Check that an invalid handle isn't accepted.
+ HMONITOR invalid_monitor = reinterpret_cast<HMONITOR>(-1);
+ monitor_info.cbSize = sizeof(MONITORINFO);
+ if (::GetMonitorInfoW(invalid_monitor, &monitor_info))
+ return SBOX_TEST_SEVENTH_ERROR;
+
+ return SBOX_TEST_SUCCEEDED;
+}
+
+bool RunTestsOnVideoOutputConfigure(uintptr_t monitor_index,
+ IOPMVideoOutput* video_output) {
+ OPM_CONFIGURE_PARAMETERS config_params = {};
+ OPM_SET_PROTECTION_LEVEL_PARAMETERS* protection_level =
+ reinterpret_cast<OPM_SET_PROTECTION_LEVEL_PARAMETERS*>(
+ config_params.abParameters);
+ protection_level->ulProtectionType = OPM_PROTECTION_TYPE_HDCP;
+ protection_level->ulProtectionLevel = OPM_HDCP_ON;
+ config_params.guidSetting = OPM_SET_PROTECTION_LEVEL;
+ config_params.cbParametersSize = sizeof(OPM_SET_PROTECTION_LEVEL_PARAMETERS);
+ HRESULT hr = video_output->Configure(&config_params, 0, nullptr);
+ if (FAILED(hr))
+ return false;
+ protection_level->ulProtectionType = OPM_PROTECTION_TYPE_DPCP;
+ hr = video_output->Configure(&config_params, 0, nullptr);
+ if (FAILED(hr))
+ return false;
+ protection_level->ulProtectionLevel = OPM_HDCP_OFF;
+ hr = video_output->Configure(&config_params, 0, nullptr);
+ if (FAILED(hr))
+ return false;
+ BYTE dummy_byte = 0;
+ hr = video_output->Configure(&config_params, 1, &dummy_byte);
+ if (SUCCEEDED(hr))
+ return false;
+ protection_level->ulProtectionType = 0xFFFFFFFF;
+ hr = video_output->Configure(&config_params, 0, nullptr);
+ if (SUCCEEDED(hr))
+ return false;
+ // Invalid protection level test.
+ protection_level->ulProtectionType = OPM_PROTECTION_TYPE_HDCP;
+ protection_level->ulProtectionLevel = OPM_HDCP_ON + 1;
+ hr = video_output->Configure(&config_params, 0, nullptr);
+ if (SUCCEEDED(hr))
+ return false;
+ hr = video_output->Configure(&config_params, 0, nullptr);
+ if (SUCCEEDED(hr))
+ return false;
+ config_params.guidSetting = OPM_SET_HDCP_SRM;
+ OPM_SET_HDCP_SRM_PARAMETERS* srm_parameters =
+ reinterpret_cast<OPM_SET_HDCP_SRM_PARAMETERS*>(
+ config_params.abParameters);
+ srm_parameters->ulSRMVersion = 1;
+ config_params.cbParametersSize = sizeof(OPM_SET_HDCP_SRM_PARAMETERS);
+ hr = video_output->Configure(&config_params, 0, nullptr);
+ if (SUCCEEDED(hr))
+ return false;
+ return true;
+}
+
+bool RunTestsOnVideoOutputFinishInitialization(uintptr_t monitor_index,
+ IOPMVideoOutput* video_output) {
+ OPM_ENCRYPTED_INITIALIZATION_PARAMETERS init_params = {};
+ memset(init_params.abEncryptedInitializationParameters, 'a' + monitor_index,
+ sizeof(init_params.abEncryptedInitializationParameters));
+ HRESULT hr = video_output->FinishInitialization(&init_params);
+ if (FAILED(hr))
+ return false;
+ memset(init_params.abEncryptedInitializationParameters, 'Z' + monitor_index,
+ sizeof(init_params.abEncryptedInitializationParameters));
+ hr = video_output->FinishInitialization(&init_params);
+ if (SUCCEEDED(hr))
+ return false;
+ return true;
+}
+
+bool RunTestsOnVideoOutputStartInitialization(uintptr_t monitor_index,
+ IOPMVideoOutput* video_output) {
+ OPM_RANDOM_NUMBER random_number = {};
+ BYTE* certificate = nullptr;
+ ULONG certificate_length = 0;
+
+ HRESULT hr = video_output->StartInitialization(&random_number, &certificate,
+ &certificate_length);
+ if (FAILED(hr))
+ return false;
+
+ if (certificate_length != CalculateCertLength(monitor_index))
+ return false;
+
+ for (ULONG i = 0; i < certificate_length; ++i) {
+ if (certificate[i] != 'A' + monitor_index)
+ return false;
+ }
+
+ for (ULONG i = 0; i < sizeof(random_number.abRandomNumber); ++i) {
+ if (random_number.abRandomNumber[i] != '!' + monitor_index)
+ return false;
+ }
+
+ return true;
+}
+
+static bool SendSingleGetInfoRequest(uintptr_t monitor_index,
+ IOPMVideoOutput* video_output,
+ const GUID& request,
+ ULONG data_length,
+ void* data) {
+ OPM_GET_INFO_PARAMETERS params = {};
+ OPM_REQUESTED_INFORMATION requested_information = {};
+ BYTE* requested_information_ptr =
+ reinterpret_cast<BYTE*>(&requested_information);
+ params.guidInformation = request;
+ params.cbParametersSize = data_length;
+ memcpy(params.abParameters, data, data_length);
+ HRESULT hr = video_output->GetInformation(&params, &requested_information);
+ if (FAILED(hr))
+ return false;
+ for (size_t i = 0; i < sizeof(OPM_REQUESTED_INFORMATION); ++i) {
+ if (requested_information_ptr[i] != '0' + monitor_index)
+ return false;
+ }
+ return true;
+}
+
+bool RunTestsOnVideoOutputGetInformation(uintptr_t monitor_index,
+ IOPMVideoOutput* video_output) {
+ ULONG dummy = 0;
+ if (!SendSingleGetInfoRequest(monitor_index, video_output,
+ OPM_GET_CONNECTOR_TYPE, 0, nullptr)) {
+ return false;
+ }
+ if (!SendSingleGetInfoRequest(monitor_index, video_output,
+ OPM_GET_SUPPORTED_PROTECTION_TYPES, 0,
+ nullptr)) {
+ return false;
+ }
+ // These should fail due to invalid parameter sizes.
+ if (SendSingleGetInfoRequest(monitor_index, video_output,
+ OPM_GET_CONNECTOR_TYPE, sizeof(dummy), &dummy)) {
+ return false;
+ }
+ if (SendSingleGetInfoRequest(monitor_index, video_output,
+ OPM_GET_SUPPORTED_PROTECTION_TYPES,
+ sizeof(dummy), &dummy)) {
+ return false;
+ }
+ ULONG protection_type = OPM_PROTECTION_TYPE_HDCP;
+ if (!SendSingleGetInfoRequest(monitor_index, video_output,
+ OPM_GET_ACTUAL_PROTECTION_LEVEL,
+ sizeof(protection_type), &protection_type)) {
+ return false;
+ }
+ protection_type = OPM_PROTECTION_TYPE_DPCP;
+ if (!SendSingleGetInfoRequest(monitor_index, video_output,
+ OPM_GET_ACTUAL_PROTECTION_LEVEL,
+ sizeof(protection_type), &protection_type)) {
+ return false;
+ }
+ // These should fail as unsupported or invalid parameters.
+ protection_type = OPM_PROTECTION_TYPE_ACP;
+ if (SendSingleGetInfoRequest(monitor_index, video_output,
+ OPM_GET_ACTUAL_PROTECTION_LEVEL,
+ sizeof(protection_type), &protection_type)) {
+ return false;
+ }
+ if (SendSingleGetInfoRequest(monitor_index, video_output,
+ OPM_GET_ACTUAL_PROTECTION_LEVEL, 0, nullptr)) {
+ return false;
+ }
+ protection_type = OPM_PROTECTION_TYPE_HDCP;
+ if (!SendSingleGetInfoRequest(monitor_index, video_output,
+ OPM_GET_VIRTUAL_PROTECTION_LEVEL,
+ sizeof(protection_type), &protection_type)) {
+ return false;
+ }
+ protection_type = OPM_PROTECTION_TYPE_DPCP;
+ if (!SendSingleGetInfoRequest(monitor_index, video_output,
+ OPM_GET_VIRTUAL_PROTECTION_LEVEL,
+ sizeof(protection_type), &protection_type)) {
+ return false;
+ }
+ // These should fail as unsupported or invalid parameters.
+ protection_type = OPM_PROTECTION_TYPE_ACP;
+ if (SendSingleGetInfoRequest(monitor_index, video_output,
+ OPM_GET_VIRTUAL_PROTECTION_LEVEL,
+ sizeof(protection_type), &protection_type)) {
+ return false;
+ }
+ if (SendSingleGetInfoRequest(monitor_index, video_output,
+ OPM_GET_VIRTUAL_PROTECTION_LEVEL, 0, nullptr)) {
+ return false;
+ }
+ // This should fail with unsupported request.
+ if (SendSingleGetInfoRequest(monitor_index, video_output, OPM_GET_CODEC_INFO,
+ 0, nullptr)) {
+ return false;
+ }
+ return true;
+}
+
+int RunTestsOnVideoOutput(uintptr_t monitor_index,
+ IOPMVideoOutput* video_output) {
+ if (!RunTestsOnVideoOutputStartInitialization(monitor_index, video_output))
+ return SBOX_TEST_FIRST_ERROR;
+
+ if (!RunTestsOnVideoOutputFinishInitialization(monitor_index, video_output))
+ return SBOX_TEST_SECOND_ERROR;
+
+ if (!RunTestsOnVideoOutputConfigure(monitor_index, video_output))
+ return SBOX_TEST_THIRD_ERROR;
+
+ if (!RunTestsOnVideoOutputGetInformation(monitor_index, video_output))
+ return SBOX_TEST_FOURTH_ERROR;
+
+ return SBOX_TEST_SUCCEEDED;
+}
+
+SBOX_TESTS_COMMAND int CheckWin8OPMApis(int argc, wchar_t** argv) {
+ std::map<HMONITOR, base::string16> monitors = GetTestMonitors();
+ for (const auto& monitor : monitors) {
+ ULONG output_count = 0;
+ IOPMVideoOutput** outputs = nullptr;
+ uintptr_t monitor_index = reinterpret_cast<uintptr_t>(monitor.first) & 0xF;
+ HRESULT hr = OPMGetVideoOutputsFromHMONITOR(
+ monitor.first, OPM_VOS_OPM_SEMANTICS, &output_count, &outputs);
+ if (monitor_index > 4) {
+ // These should fail because the certificate is too large.
+ if (SUCCEEDED(hr))
+ return SBOX_TEST_FIRST_ERROR;
+ continue;
+ }
+ if (FAILED(hr))
+ return SBOX_TEST_SECOND_ERROR;
+ if (output_count != monitor_index - 1)
+ return SBOX_TEST_THIRD_ERROR;
+ for (ULONG output_index = 0; output_index < output_count; ++output_index) {
+ int result = RunTestsOnVideoOutput(monitor_index, outputs[output_index]);
+ outputs[output_index]->Release();
+ if (result != SBOX_TEST_SUCCEEDED)
+ return result;
+ }
+ ::CoTaskMemFree(outputs);
+ }
+ return SBOX_TEST_SUCCEEDED;
+}
+
// This test validates that setting the MITIGATION_WIN32K_DISABLE mitigation on
// the target process causes the launch to fail in process initialization.
// The test process itself links against user32/gdi32.
@@ -404,6 +989,8 @@ TEST(ProcessMitigationsTest, CheckWin8Win32KLockDownSuccess) {
TestRunner runner;
sandbox::TargetPolicy* policy = runner.GetPolicy();
+ ProcessMitigationsWin32KLockdownPolicy::SetOverrideForTestCallback(
+ FunctionOverrideForTest);
EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_WIN32K_DISABLE),
SBOX_ALL_OK);
@@ -411,6 +998,34 @@ TEST(ProcessMitigationsTest, CheckWin8Win32KLockDownSuccess) {
sandbox::TargetPolicy::FAKE_USER_GDI_INIT, NULL),
sandbox::SBOX_ALL_OK);
EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8Lockdown"));
+ EXPECT_NE(SBOX_TEST_SUCCEEDED,
+ runner.RunTest(L"CheckWin8MonitorsRedirection"));
+ EXPECT_NE(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8MonitorInfo"));
+ EXPECT_NE(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8OPMApis"));
+}
+
+// This test validates the even though we're running under win32k lockdown
+// we can use the IPC redirection to enumerate the list of monitors.
+TEST(ProcessMitigationsTest, CheckWin8Win32KRedirection) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ return;
+
+ TestRunner runner;
+ sandbox::TargetPolicy* policy = runner.GetPolicy();
+ ProcessMitigationsWin32KLockdownPolicy::SetOverrideForTestCallback(
+ FunctionOverrideForTest);
+
+ EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_WIN32K_DISABLE),
+ SBOX_ALL_OK);
+ EXPECT_EQ(policy->AddRule(sandbox::TargetPolicy::SUBSYS_WIN32K_LOCKDOWN,
+ sandbox::TargetPolicy::IMPLEMENT_OPM_APIS, NULL),
+ sandbox::SBOX_ALL_OK);
+ policy->SetEnableOPMRedirection();
+ EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8Lockdown"));
+ EXPECT_EQ(SBOX_TEST_SUCCEEDED,
+ runner.RunTest(L"CheckWin8MonitorsRedirection"));
+ EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8MonitorInfo"));
+ EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8OPMApis"));
}
//------------------------------------------------------------------------------
« no previous file with comments | « sandbox/win/src/policy_low_level.h ('k') | sandbox/win/src/process_mitigations_win32k_dispatcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698