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

Unified Diff: sandbox/win/src/process_mitigations_win32k_policy.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: Replaced shared memory implementation. 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/process_mitigations_win32k_policy.h ('k') | sandbox/win/src/sandbox_policy.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sandbox/win/src/process_mitigations_win32k_policy.cc
diff --git a/sandbox/win/src/process_mitigations_win32k_policy.cc b/sandbox/win/src/process_mitigations_win32k_policy.cc
index af18c5413c2815499f21e413403d6f9fd082daec..4e5c01f13d608d07d5d13ae9666fe7d4e94be4c3 100644
--- a/sandbox/win/src/process_mitigations_win32k_policy.cc
+++ b/sandbox/win/src/process_mitigations_win32k_policy.cc
@@ -2,10 +2,86 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stddef.h>
+
+#include "sandbox/win/src/process_mitigations_win32k_interception.h"
#include "sandbox/win/src/process_mitigations_win32k_policy.h"
namespace sandbox {
+namespace {
+
+// Define GUIDs for OPM APIs
+const GUID DXGKMDT_OPM_GET_CONNECTOR_TYPE = {
+ 0x81d0bfd5,
+ 0x6afe,
+ 0x48c2,
+ {0x99, 0xc0, 0x95, 0xa0, 0x8f, 0x97, 0xc5, 0xda}};
+const GUID DXGKMDT_OPM_GET_SUPPORTED_PROTECTION_TYPES = {
+ 0x38f2a801,
+ 0x9a6c,
+ 0x48bb,
+ {0x91, 0x07, 0xb6, 0x69, 0x6e, 0x6f, 0x17, 0x97}};
+const GUID DXGKMDT_OPM_GET_VIRTUAL_PROTECTION_LEVEL = {
+ 0xb2075857,
+ 0x3eda,
+ 0x4d5d,
+ {0x88, 0xdb, 0x74, 0x8f, 0x8c, 0x1a, 0x05, 0x49}};
+const GUID DXGKMDT_OPM_GET_ACTUAL_PROTECTION_LEVEL = {
+ 0x1957210a,
+ 0x7766,
+ 0x452a,
+ {0xb9, 0x9a, 0xd2, 0x7a, 0xed, 0x54, 0xf0, 0x3a}};
+const GUID DXGKMDT_OPM_SET_PROTECTION_LEVEL = {
+ 0x9bb9327c,
+ 0x4eb5,
+ 0x4727,
+ {0x9f, 0x00, 0xb4, 0x2b, 0x09, 0x19, 0xc0, 0xda}};
+
+void StringToUnicodeString(PUNICODE_STRING unicode_string,
+ const base::string16& device_name) {
+ static RtlInitUnicodeStringFunction RtlInitUnicodeString;
+ if (!RtlInitUnicodeString) {
+ HMODULE ntdll = ::GetModuleHandle(kNtdllName);
+ RtlInitUnicodeString = reinterpret_cast<RtlInitUnicodeStringFunction>(
+ GetProcAddress(ntdll, "RtlInitUnicodeString"));
+ DCHECK(!!RtlInitUnicodeString);
+ }
+ RtlInitUnicodeString(unicode_string, device_name.c_str());
+}
+
+struct MonitorListState {
+ HMONITOR* monitor_list;
+ uint32_t monitor_list_size;
+ uint32_t monitor_list_pos;
+};
+
+BOOL CALLBACK DisplayMonitorEnumProc(HMONITOR monitor,
+ HDC hdc_monitor,
+ LPRECT rect_monitor,
+ LPARAM data) {
+ MonitorListState* state = reinterpret_cast<MonitorListState*>(data);
+ if (state->monitor_list_pos >= state->monitor_list_size)
+ return FALSE;
+ state->monitor_list[state->monitor_list_pos++] = monitor;
+ return TRUE;
+}
+
+template <typename T>
+T GetGdi32Func(const char* name) {
+ static T func = nullptr;
+ if (!func) {
+ func = reinterpret_cast<T>(
+ ::GetProcAddress(::GetModuleHandle(L"gdi32.dll"), name));
+ DCHECK(!!func);
+ }
+ return func;
+}
+
+#define GDIFUNC(name) GetGdi32Func<name##Function>(#name)
+
+} // namespace
+
bool ProcessMitigationsWin32KLockdownPolicy::GenerateRules(
const wchar_t* name,
TargetPolicy::Semantics semantics,
@@ -17,8 +93,191 @@ bool ProcessMitigationsWin32KLockdownPolicy::GenerateRules(
return false;
if (!policy->AddRule(IPC_USER_REGISTERCLASSW_TAG, &rule))
return false;
+ if (semantics != TargetPolicy::IMPLEMENT_OPM_APIS)
+ return true;
+ if (!policy->AddRule(IPC_USER_ENUMDISPLAYMONITORS_TAG, &rule))
+ return false;
+ if (!policy->AddRule(IPC_USER_ENUMDISPLAYDEVICES_TAG, &rule))
+ return false;
+ if (!policy->AddRule(IPC_USER_GETMONITORINFO_TAG, &rule))
+ return false;
+ if (!policy->AddRule(IPC_GDI_CREATEOPMPROTECTEDOUTPUTS_TAG, &rule))
+ return false;
+ if (!policy->AddRule(IPC_GDI_GETCERTIFICATE_TAG, &rule))
+ return false;
+ if (!policy->AddRule(IPC_GDI_GETCERTIFICATESIZE_TAG, &rule))
+ return false;
+ if (!policy->AddRule(IPC_GDI_DESTROYOPMPROTECTEDOUTPUT_TAG, &rule))
+ return false;
+ if (!policy->AddRule(IPC_GDI_CONFIGUREOPMPROTECTEDOUTPUT_TAG, &rule))
+ return false;
+ if (!policy->AddRule(IPC_GDI_GETOPMINFORMATION_TAG, &rule))
+ return false;
+ if (!policy->AddRule(IPC_GDI_GETOPMRANDOMNUMBER_TAG, &rule))
+ return false;
+ if (!policy->AddRule(IPC_GDI_GETSUGGESTEDOPMPROTECTEDOUTPUTARRAYSIZE_TAG,
+ &rule))
+ return false;
+ if (!policy->AddRule(IPC_GDI_SETOPMSIGNINGKEYANDSEQUENCENUMBERS_TAG, &rule))
+ return false;
return true;
}
+uint32_t ProcessMitigationsWin32KLockdownPolicy::EnumDisplayMonitorsAction(
+ const ClientInfo& client_info,
+ HMONITOR* monitor_list,
+ uint32_t monitor_list_size) {
+ MonitorListState state = {monitor_list, monitor_list_size, 0};
+ EnumDisplayMonitors(nullptr, nullptr, DisplayMonitorEnumProc,
+ reinterpret_cast<LPARAM>(&state));
+ return state.monitor_list_pos;
+}
+
+NTSTATUS ProcessMitigationsWin32KLockdownPolicy::
+ GetSuggestedOPMProtectedOutputArraySizeAction(
+ const ClientInfo& client_info,
+ const base::string16& device_name,
+ uint32_t* suggested_array_size) {
+ UNICODE_STRING unicode_device_name;
+ StringToUnicodeString(&unicode_device_name, device_name);
+ return GDIFUNC(GetSuggestedOPMProtectedOutputArraySize)(
+ &unicode_device_name, reinterpret_cast<DWORD*>(suggested_array_size));
+}
+
+NTSTATUS
+ProcessMitigationsWin32KLockdownPolicy::CreateOPMProtectedOutputsAction(
+ const ClientInfo& client_info,
+ const base::string16& device_name,
+ HANDLE* protected_outputs,
+ uint32_t array_input_size,
+ uint32_t* array_output_size) {
+ UNICODE_STRING unicode_device_name;
+ StringToUnicodeString(&unicode_device_name, device_name);
+ DWORD output_size = 0;
+
+ NTSTATUS status = GDIFUNC(CreateOPMProtectedOutputs)(
+ &unicode_device_name, DXGKMDT_OPM_VOS_OPM_SEMANTICS, array_input_size,
+ &output_size,
+ reinterpret_cast<OPM_PROTECTED_OUTPUT_HANDLE*>(protected_outputs));
+ if (!status)
+ *array_output_size = output_size;
+ return status;
+}
+
+NTSTATUS ProcessMitigationsWin32KLockdownPolicy::GetCertificateSizeAction(
+ const ClientInfo& client_info,
+ const base::string16& device_name,
+ uint32_t* cert_size) {
+ UNICODE_STRING unicode_device_name;
+ StringToUnicodeString(&unicode_device_name, device_name);
+
+ return GDIFUNC(GetCertificateSize)(&unicode_device_name,
+ DXGKMDT_OPM_CERTIFICATE,
+ reinterpret_cast<DWORD*>(cert_size));
+}
+
+NTSTATUS ProcessMitigationsWin32KLockdownPolicy::GetCertificateAction(
+ const ClientInfo& client_info,
+ const base::string16& device_name,
+ BYTE* cert_data,
+ uint32_t cert_size) {
+ UNICODE_STRING unicode_device_name;
+ StringToUnicodeString(&unicode_device_name, device_name);
+
+ return GDIFUNC(GetCertificate)(&unicode_device_name, DXGKMDT_OPM_CERTIFICATE,
+ cert_data, cert_size);
+}
+
+NTSTATUS ProcessMitigationsWin32KLockdownPolicy::GetOPMRandomNumberAction(
+ const ClientInfo& client_info,
+ HANDLE protected_output,
+ void* random_number) {
+ return GDIFUNC(GetOPMRandomNumber)(
+ protected_output, static_cast<DXGKMDT_OPM_RANDOM_NUMBER*>(random_number));
Will Harris 2016/04/05 03:49:02 reinterpret_cast
Will Harris 2016/04/11 21:23:02 actually static_cast here is fine.
+}
+
+NTSTATUS ProcessMitigationsWin32KLockdownPolicy::
+ SetOPMSigningKeyAndSequenceNumbersAction(const ClientInfo& client_info,
+ HANDLE protected_output,
+ void* parameters) {
+ return GDIFUNC(SetOPMSigningKeyAndSequenceNumbers)(
+ protected_output,
+ static_cast<DXGKMDT_OPM_ENCRYPTED_PARAMETERS*>(parameters));
+}
+
+NTSTATUS
+ProcessMitigationsWin32KLockdownPolicy::ConfigureOPMProtectedOutputAction(
+ const ClientInfo& client_info,
+ HANDLE protected_output,
+ void* parameters) {
+ DXGKMDT_OPM_CONFIGURE_PARAMETERS config;
+ memcpy(&config, parameters, sizeof(DXGKMDT_OPM_CONFIGURE_PARAMETERS));
+ if (config.guidSetting != DXGKMDT_OPM_SET_PROTECTION_LEVEL ||
+ config.cbParametersSize !=
+ sizeof(DXGKMDT_OPM_SET_PROTECTION_LEVEL_PARAMETERS)) {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ DXGKMDT_OPM_SET_PROTECTION_LEVEL_PARAMETERS params;
+ memcpy(&params, config.abParameters,
+ sizeof(DXGKMDT_OPM_SET_PROTECTION_LEVEL_PARAMETERS));
+ if (params.Reserved || params.Reserved2)
+ return STATUS_INVALID_PARAMETER;
+
+ if (params.ulProtectionType != DXGKMDT_OPM_PROTECTION_TYPE_HDCP &&
+ params.ulProtectionType != DXGKMDT_OPM_PROTECTION_TYPE_DPCP) {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ // Protection levels are same for HDCP and DPCP.
+ if (params.ulProtectionLevel != DXGKMDT_OPM_HDCP_OFF &&
+ params.ulProtectionLevel != DXGKMDT_OPM_HDCP_ON) {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ return GDIFUNC(ConfigureOPMProtectedOutput)(protected_output, &config, 0,
+ nullptr);
+}
+
+NTSTATUS ProcessMitigationsWin32KLockdownPolicy::GetOPMInformationAction(
+ const ClientInfo& client_info,
+ HANDLE protected_output,
+ void* parameters,
+ void* requested_information) {
+ DXGKMDT_OPM_GET_INFO_PARAMETERS params;
+ memcpy(&params, parameters, sizeof(DXGKMDT_OPM_GET_INFO_PARAMETERS));
+
+ bool valid_parameters = false;
+ // Validate sizes based on the type being requested.
+ if ((params.guidInformation == DXGKMDT_OPM_GET_CONNECTOR_TYPE ||
+ params.guidInformation == DXGKMDT_OPM_GET_SUPPORTED_PROTECTION_TYPES) &&
+ params.cbParametersSize == 0) {
+ valid_parameters = true;
+ } else if ((params.guidInformation ==
+ DXGKMDT_OPM_GET_VIRTUAL_PROTECTION_LEVEL ||
+ params.guidInformation ==
+ DXGKMDT_OPM_GET_ACTUAL_PROTECTION_LEVEL) &&
+ params.cbParametersSize == sizeof(uint32_t)) {
+ uint32_t param_value;
+ memcpy(&param_value, params.abParameters, sizeof(uint32_t));
+ if (param_value == DXGKMDT_OPM_PROTECTION_TYPE_HDCP ||
+ param_value == DXGKMDT_OPM_PROTECTION_TYPE_DPCP) {
+ valid_parameters = true;
+ }
+ }
+ if (!valid_parameters)
+ return STATUS_INVALID_PARAMETER;
+
+ return GDIFUNC(GetOPMInformation)(
+ protected_output, &params,
+ static_cast<DXGKMDT_OPM_REQUESTED_INFORMATION*>(requested_information));
+}
+
+NTSTATUS
+ProcessMitigationsWin32KLockdownPolicy::DestroyOPMProtectedOutputAction(
+ HANDLE protected_output) {
+ return GDIFUNC(DestroyOPMProtectedOutput)(protected_output);
+}
+
} // namespace sandbox
« no previous file with comments | « sandbox/win/src/process_mitigations_win32k_policy.h ('k') | sandbox/win/src/sandbox_policy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698