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

Side by Side Diff: sandbox/win/src/process_mitigations_win32k_dispatcher.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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "sandbox/win/src/process_mitigations_win32k_dispatcher.h" 5 #include "sandbox/win/src/process_mitigations_win32k_dispatcher.h"
6
7 #include <algorithm>
8
9 #include "base/memory/shared_memory.h"
10 #include "base/strings/string16.h"
6 #include "sandbox/win/src/interception.h" 11 #include "sandbox/win/src/interception.h"
7 #include "sandbox/win/src/interceptors.h" 12 #include "sandbox/win/src/interceptors.h"
8 #include "sandbox/win/src/ipc_tags.h" 13 #include "sandbox/win/src/ipc_tags.h"
9 #include "sandbox/win/src/process_mitigations_win32k_interception.h" 14 #include "sandbox/win/src/process_mitigations_win32k_interception.h"
15 #include "sandbox/win/src/process_mitigations_win32k_policy.h"
10 16
11 namespace sandbox { 17 namespace sandbox {
12 18
19 namespace {
20
21 struct ValidateMonitorParams {
22 HMONITOR monitor;
23 base::string16 device_name;
24 bool result;
25 };
26
27 bool GetMonitorDeviceName(HMONITOR monitor, base::string16* device_name) {
28 MONITORINFOEXW monitor_info = {};
29 monitor_info.cbSize = sizeof(MONITORINFOEXW);
30 if (!::GetMonitorInfoW(monitor,
31 reinterpret_cast<MONITORINFO*>(&monitor_info)))
32 return false;
33 if (monitor_info.szDevice[CCHDEVICENAME - 1] != 0)
34 return false;
35 *device_name = monitor_info.szDevice;
36 return true;
37 }
38
39 BOOL CALLBACK ValidateMonitorEnumProc(HMONITOR monitor,
40 HDC,
41 LPRECT,
42 LPARAM data) {
43 ValidateMonitorParams* valid_params =
44 reinterpret_cast<ValidateMonitorParams*>(data);
45 base::string16 device_name;
46 bool result = false;
47 if (valid_params->device_name.empty()) {
48 result = monitor == valid_params->monitor;
49 } else if (GetMonitorDeviceName(monitor, &device_name)) {
50 result = device_name == valid_params->device_name;
51 }
52 valid_params->result = result;
53 if (!result)
54 return TRUE;
55 return FALSE;
56 }
57
58 bool IsValidMonitorOrDeviceName(HMONITOR monitor, const wchar_t* device_name) {
59 ValidateMonitorParams params = {};
60 params.monitor = monitor;
61 if (device_name)
62 params.device_name = device_name;
63 ::EnumDisplayMonitors(nullptr, nullptr, ValidateMonitorEnumProc,
64 reinterpret_cast<LPARAM>(&params));
65 DCHECK(params.result);
66 return params.result;
67 }
68
69 base::SharedMemoryHandle GetSharedMemoryHandle(const ClientInfo& client_info,
70 HANDLE handle) {
71 HANDLE result_handle = nullptr;
72 intptr_t handle_int = reinterpret_cast<intptr_t>(handle);
73 if (handle_int <= 0 ||
74 !::DuplicateHandle(client_info.process, handle, ::GetCurrentProcess(),
75 &result_handle, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
76 result_handle = nullptr;
77 }
78 return base::SharedMemoryHandle(result_handle, ::GetCurrentProcessId());
79 }
80
81 } // namespace
82
83 ProtectedVideoOutput::~ProtectedVideoOutput() {
84 ProcessMitigationsWin32KLockdownPolicy::DestroyOPMProtectedOutputAction(
85 handle_);
86 }
87
88 scoped_refptr<ProtectedVideoOutput>
89 ProcessMitigationsWin32KDispatcher::GetProtectedVideoOutput(
90 HANDLE handle,
91 bool destroy_output) {
92 base::AutoLock lock(protected_outputs_lock_);
93 scoped_refptr<ProtectedVideoOutput> result;
94 auto it = protected_outputs_.find(handle);
95 if (it != protected_outputs_.end()) {
96 result = it->second;
97 if (destroy_output)
98 protected_outputs_.erase(it);
99 }
100 return result;
101 }
102
13 ProcessMitigationsWin32KDispatcher::ProcessMitigationsWin32KDispatcher( 103 ProcessMitigationsWin32KDispatcher::ProcessMitigationsWin32KDispatcher(
14 PolicyBase* policy_base) 104 PolicyBase* policy_base)
15 : policy_base_(policy_base) { 105 : policy_base_(policy_base) {
106 static const IPCCall enum_display_monitors_params = {
107 {IPC_USER_ENUMDISPLAYMONITORS_TAG, {INOUTPTR_TYPE}},
108 reinterpret_cast<CallbackGeneric>(
109 &ProcessMitigationsWin32KDispatcher::EnumDisplayMonitors)};
110 static const IPCCall get_monitor_info_params = {
111 {IPC_USER_GETMONITORINFO_TAG, {VOIDPTR_TYPE, INOUTPTR_TYPE}},
112 reinterpret_cast<CallbackGeneric>(
113 &ProcessMitigationsWin32KDispatcher::GetMonitorInfo)};
114 static const IPCCall get_suggested_output_size_params = {
115 {IPC_GDI_GETSUGGESTEDOPMPROTECTEDOUTPUTARRAYSIZE_TAG, {WCHAR_TYPE}},
116 reinterpret_cast<CallbackGeneric>(
117 &ProcessMitigationsWin32KDispatcher::
118 GetSuggestedOPMProtectedOutputArraySize)};
119 static const IPCCall create_protected_outputs_params = {
120 {IPC_GDI_CREATEOPMPROTECTEDOUTPUTS_TAG, {WCHAR_TYPE, INOUTPTR_TYPE}},
121 reinterpret_cast<CallbackGeneric>(
122 &ProcessMitigationsWin32KDispatcher::CreateOPMProtectedOutputs)};
123 static const IPCCall get_cert_size_params = {
124 {IPC_GDI_GETCERTIFICATESIZE_TAG, {WCHAR_TYPE}},
125 reinterpret_cast<CallbackGeneric>(
126 &ProcessMitigationsWin32KDispatcher::GetCertificateSize)};
127 static const IPCCall get_cert_params = {
128 {IPC_GDI_GETCERTIFICATE_TAG, {WCHAR_TYPE, VOIDPTR_TYPE, UINT32_TYPE}},
129 reinterpret_cast<CallbackGeneric>(
130 &ProcessMitigationsWin32KDispatcher::GetCertificate)};
131 static const IPCCall destroy_protected_output_params = {
132 {IPC_GDI_DESTROYOPMPROTECTEDOUTPUT_TAG, {VOIDPTR_TYPE}},
133 reinterpret_cast<CallbackGeneric>(
134 &ProcessMitigationsWin32KDispatcher::DestroyOPMProtectedOutput)};
135 static const IPCCall get_random_number_params = {
136 {IPC_GDI_GETOPMRANDOMNUMBER_TAG, {VOIDPTR_TYPE, INOUTPTR_TYPE}},
137 reinterpret_cast<CallbackGeneric>(
138 &ProcessMitigationsWin32KDispatcher::GetOPMRandomNumber)};
139 static const IPCCall set_signing_key_params = {
140 {IPC_GDI_SETOPMSIGNINGKEYANDSEQUENCENUMBERS_TAG,
141 {VOIDPTR_TYPE, INOUTPTR_TYPE}},
142 reinterpret_cast<CallbackGeneric>(
143 &ProcessMitigationsWin32KDispatcher::
144 SetOPMSigningKeyAndSequenceNumbers)};
145 static const IPCCall configure_protected_output_params = {
146 {IPC_GDI_CONFIGUREOPMPROTECTEDOUTPUT_TAG, {VOIDPTR_TYPE, VOIDPTR_TYPE}},
147 reinterpret_cast<CallbackGeneric>(
148 &ProcessMitigationsWin32KDispatcher::ConfigureOPMProtectedOutput)};
149 static const IPCCall get_information_params = {
150 {IPC_GDI_GETOPMINFORMATION_TAG, {VOIDPTR_TYPE, VOIDPTR_TYPE}},
151 reinterpret_cast<CallbackGeneric>(
152 &ProcessMitigationsWin32KDispatcher::GetOPMInformation)};
153
154 ipc_calls_.push_back(enum_display_monitors_params);
155 ipc_calls_.push_back(get_monitor_info_params);
156 ipc_calls_.push_back(get_suggested_output_size_params);
157 ipc_calls_.push_back(create_protected_outputs_params);
158 ipc_calls_.push_back(get_cert_size_params);
159 ipc_calls_.push_back(get_cert_params);
160 ipc_calls_.push_back(destroy_protected_output_params);
161 ipc_calls_.push_back(get_random_number_params);
162 ipc_calls_.push_back(set_signing_key_params);
163 ipc_calls_.push_back(configure_protected_output_params);
164 ipc_calls_.push_back(get_information_params);
16 } 165 }
17 166
167 ProcessMitigationsWin32KDispatcher::~ProcessMitigationsWin32KDispatcher() {}
168
18 bool ProcessMitigationsWin32KDispatcher::SetupService( 169 bool ProcessMitigationsWin32KDispatcher::SetupService(
19 InterceptionManager* manager, int service) { 170 InterceptionManager* manager, int service) {
20 if (!(policy_base_->GetProcessMitigations() & 171 if (!(policy_base_->GetProcessMitigations() &
21 sandbox::MITIGATION_WIN32K_DISABLE)) { 172 sandbox::MITIGATION_WIN32K_DISABLE)) {
22 return false; 173 return false;
23 } 174 }
24 175
25 switch (service) { 176 switch (service) {
26 case IPC_GDI_GDIDLLINITIALIZE_TAG: { 177 case IPC_GDI_GDIDLLINITIALIZE_TAG: {
27 if (!INTERCEPT_EAT(manager, L"gdi32.dll", GdiDllInitialize, 178 if (!INTERCEPT_EAT(manager, L"gdi32.dll", GdiDllInitialize,
(...skipping 12 matching lines...) Expand all
40 } 191 }
41 192
42 case IPC_USER_REGISTERCLASSW_TAG: { 193 case IPC_USER_REGISTERCLASSW_TAG: {
43 if (!INTERCEPT_EAT(manager, L"user32.dll", RegisterClassW, 194 if (!INTERCEPT_EAT(manager, L"user32.dll", RegisterClassW,
44 REGISTERCLASSW_ID, 8)) { 195 REGISTERCLASSW_ID, 8)) {
45 return false; 196 return false;
46 } 197 }
47 return true; 198 return true;
48 } 199 }
49 200
201 case IPC_USER_ENUMDISPLAYMONITORS_TAG: {
202 if (!INTERCEPT_EAT(manager, L"user32.dll", EnumDisplayMonitors,
203 ENUMDISPLAYMONITORS_ID, 20)) {
204 return false;
205 }
206 return true;
207 }
208
209 case IPC_USER_ENUMDISPLAYDEVICES_TAG: {
210 if (!INTERCEPT_EAT(manager, L"user32.dll", EnumDisplayDevicesA,
211 ENUMDISPLAYDEVICESA_ID, 20)) {
212 return false;
213 }
214 return true;
215 }
216
217 case IPC_USER_GETMONITORINFO_TAG: {
218 if (!INTERCEPT_EAT(manager, L"user32.dll", GetMonitorInfoA,
219 GETMONITORINFOA_ID, 12)) {
220 return false;
221 }
222 if (!INTERCEPT_EAT(manager, L"user32.dll", GetMonitorInfoW,
223 GETMONITORINFOW_ID, 12)) {
224 return false;
225 }
226 return true;
227 }
228
229 case IPC_GDI_CREATEOPMPROTECTEDOUTPUTS_TAG:
230 if (!INTERCEPT_EAT(manager, L"gdi32.dll", CreateOPMProtectedOutputs,
231 CREATEOPMPROTECTEDOUTPUTS_ID, 24)) {
232 return false;
233 }
234 return true;
235 case IPC_GDI_GETCERTIFICATE_TAG:
236 if (!INTERCEPT_EAT(manager, L"gdi32.dll", GetCertificate,
237 GETCERTIFICATE_ID, 20)) {
238 return false;
239 }
240 return true;
241 case IPC_GDI_GETCERTIFICATESIZE_TAG:
242 if (!INTERCEPT_EAT(manager, L"gdi32.dll", GetCertificateSize,
243 GETCERTIFICATESIZE_ID, 16)) {
244 return false;
245 }
246 return true;
247 case IPC_GDI_DESTROYOPMPROTECTEDOUTPUT_TAG:
248 if (!INTERCEPT_EAT(manager, L"gdi32.dll", DestroyOPMProtectedOutput,
249 DESTROYOPMPROTECTEDOUTPUT_ID, 8)) {
250 return false;
251 }
252 return true;
253 case IPC_GDI_CONFIGUREOPMPROTECTEDOUTPUT_TAG:
254 if (!INTERCEPT_EAT(manager, L"gdi32.dll", ConfigureOPMProtectedOutput,
255 CONFIGUREOPMPROTECTEDOUTPUT_ID, 20)) {
256 return false;
257 }
258 return true;
259 case IPC_GDI_GETOPMINFORMATION_TAG:
260 if (!INTERCEPT_EAT(manager, L"gdi32.dll", GetOPMInformation,
261 GETOPMINFORMATION_ID, 16)) {
262 return false;
263 }
264 return true;
265 case IPC_GDI_GETOPMRANDOMNUMBER_TAG:
266 if (!INTERCEPT_EAT(manager, L"gdi32.dll", GetOPMRandomNumber,
267 GETOPMRANDOMNUMBER_ID, 12)) {
268 return false;
269 }
270 return true;
271 case IPC_GDI_GETSUGGESTEDOPMPROTECTEDOUTPUTARRAYSIZE_TAG:
272 if (!INTERCEPT_EAT(manager, L"gdi32.dll",
273 GetSuggestedOPMProtectedOutputArraySize,
274 GETSUGGESTEDOPMPROTECTEDOUTPUTARRAYSIZE_ID, 12)) {
275 return false;
276 }
277 return true;
278 case IPC_GDI_SETOPMSIGNINGKEYANDSEQUENCENUMBERS_TAG:
279 if (!INTERCEPT_EAT(manager, L"gdi32.dll",
280 SetOPMSigningKeyAndSequenceNumbers,
281 SETOPMSIGNINGKEYANDSEQUENCENUMBERS_ID, 12)) {
282 return false;
283 }
284 return true;
285
50 default: 286 default:
51 break; 287 break;
52 } 288 }
53 return false; 289 return false;
54 } 290 }
55 291
292 bool ProcessMitigationsWin32KDispatcher::EnumDisplayMonitors(
293 IPCInfo* ipc,
294 CountedBuffer* buffer) {
295 if (!policy_base_->GetEnableOPMRedirection()) {
296 ipc->return_info.win32_result = ERROR_ACCESS_DENIED;
297 return true;
298 }
299
300 if (buffer->Size() != sizeof(EnumMonitorsResult)) {
301 ipc->return_info.win32_result = ERROR_INVALID_PARAMETER;
302 return true;
303 }
304 HMONITOR monitor_list[kMaxEnumMonitors] = {};
305
306 uint32_t monitor_list_count =
307 ProcessMitigationsWin32KLockdownPolicy::EnumDisplayMonitorsAction(
308 *ipc->client_info, monitor_list, kMaxEnumMonitors);
309 DCHECK(monitor_list_count <= kMaxEnumMonitors);
310
311 EnumMonitorsResult* result =
312 static_cast<EnumMonitorsResult*>(buffer->Buffer());
313 for (uint32_t monitor_pos = 0; monitor_pos < monitor_list_count;
314 ++monitor_pos) {
315 result->monitors[monitor_pos] = monitor_list[monitor_pos];
316 }
317 result->monitor_count = monitor_list_count;
318 ipc->return_info.win32_result = 0;
319
320 return true;
321 }
322
323 bool ProcessMitigationsWin32KDispatcher::GetMonitorInfo(IPCInfo* ipc,
324 void* monitor,
325 CountedBuffer* buffer) {
326 if (!policy_base_->GetEnableOPMRedirection()) {
327 ipc->return_info.win32_result = ERROR_ACCESS_DENIED;
328 return true;
329 }
330 if (buffer->Size() < sizeof(MONITORINFO)) {
331 ipc->return_info.win32_result = ERROR_INVALID_PARAMETER;
332 return true;
333 }
334 MONITORINFO* monitor_info = static_cast<MONITORINFO*>(buffer->Buffer());
335 BOOL success = FALSE;
336 // Ensure size is valid and represents what we've been passed.
337 monitor_info->cbSize = buffer->Size();
338 HMONITOR monitor_handle = static_cast<HMONITOR>(monitor);
339 if (!IsValidMonitorOrDeviceName(monitor_handle, nullptr)) {
340 ipc->return_info.win32_result = ERROR_ACCESS_DENIED;
341 return true;
342 }
343 if (buffer->Size() == sizeof(MONITORINFO) ||
344 buffer->Size() == sizeof(MONITORINFOEXW))
345 success = ::GetMonitorInfoW(monitor_handle, monitor_info);
346 else if (buffer->Size() == sizeof(MONITORINFOEXA))
347 success = ::GetMonitorInfoA(monitor_handle, monitor_info);
348 ipc->return_info.win32_result =
349 success ? ERROR_SUCCESS : ERROR_INVALID_PARAMETER;
350 return true;
351 }
352
353 bool ProcessMitigationsWin32KDispatcher::
354 GetSuggestedOPMProtectedOutputArraySize(IPCInfo* ipc,
355 base::string16* device_name) {
356 if (!policy_base_->GetEnableOPMRedirection()) {
357 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
358 return true;
359 }
360 if (!IsValidMonitorOrDeviceName(nullptr, device_name->c_str())) {
361 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
362 return true;
363 }
364 NTSTATUS status = ProcessMitigationsWin32KLockdownPolicy::
365 GetSuggestedOPMProtectedOutputArraySizeAction(
366 *ipc->client_info, *device_name,
367 &ipc->return_info.extended[0].unsigned_int);
368 if (!status) {
369 ipc->return_info.extended_count = 1;
370 }
371 ipc->return_info.nt_status = status;
372 return true;
373 }
374
375 bool ProcessMitigationsWin32KDispatcher::CreateOPMProtectedOutputs(
376 IPCInfo* ipc,
377 base::string16* device_name,
378 CountedBuffer* protected_outputs) {
379 if (!policy_base_->GetEnableOPMRedirection()) {
380 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
381 return true;
382 }
383 if (!IsValidMonitorOrDeviceName(nullptr, device_name->c_str())) {
384 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
385 return true;
386 }
387 uint32_t output_array_size = 0;
388 uint32_t input_array_size = protected_outputs->Size() / sizeof(HANDLE);
389 HANDLE* handles = static_cast<HANDLE*>(protected_outputs->Buffer());
390 NTSTATUS status =
391 ProcessMitigationsWin32KLockdownPolicy::CreateOPMProtectedOutputsAction(
392 *ipc->client_info, *device_name, handles, input_array_size,
393 &output_array_size);
394 if (!status && (output_array_size <= input_array_size)) {
395 base::AutoLock lock(protected_outputs_lock_);
396 ipc->return_info.extended_count = 1;
397 ipc->return_info.extended[0].unsigned_int = output_array_size;
398 for (uint32_t handle_pos = 0; handle_pos < output_array_size;
399 handle_pos++) {
400 HANDLE handle = handles[handle_pos];
401 protected_outputs_[handle] = new ProtectedVideoOutput(handle);
402 }
403 }
404 ipc->return_info.nt_status = status;
405 return true;
406 }
407
408 bool ProcessMitigationsWin32KDispatcher::GetCertificateSize(
409 IPCInfo* ipc,
410 base::string16* device_name) {
411 if (!policy_base_->GetEnableOPMRedirection()) {
412 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
413 return true;
414 }
415 if (!IsValidMonitorOrDeviceName(nullptr, device_name->c_str())) {
416 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
417 return true;
418 }
419 NTSTATUS status =
420 ProcessMitigationsWin32KLockdownPolicy::GetCertificateSizeAction(
421 *ipc->client_info, *device_name,
422 &ipc->return_info.extended[0].unsigned_int);
423 if (!status) {
424 ipc->return_info.extended_count = 1;
425 }
426 ipc->return_info.nt_status = status;
427 return true;
428 }
429
430 bool ProcessMitigationsWin32KDispatcher::GetCertificate(
431 IPCInfo* ipc,
432 base::string16* device_name,
433 void* shared_buffer_handle,
434 uint32_t shared_buffer_size) {
435 if (!policy_base_->GetEnableOPMRedirection()) {
436 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
437 return true;
438 }
439 if (!IsValidMonitorOrDeviceName(nullptr, device_name->c_str())) {
440 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
441 return true;
442 }
443 // Don't let caller map an arbitrarily large buffer into memory.
444 if (shared_buffer_size > kProtectedVideoOutputSectionSize) {
445 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
446 return true;
447 }
448 base::SharedMemoryHandle handle =
449 GetSharedMemoryHandle(*ipc->client_info, shared_buffer_handle);
450 if (!handle.IsValid()) {
451 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
452 return true;
453 }
454 base::SharedMemory cert_data(handle, false);
455 if (!cert_data.Map(shared_buffer_size)) {
456 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
457 return true;
458 }
459 NTSTATUS status =
460 ProcessMitigationsWin32KLockdownPolicy::GetCertificateAction(
461 *ipc->client_info, *device_name,
462 static_cast<BYTE*>(cert_data.memory()), shared_buffer_size);
463 ipc->return_info.nt_status = status;
464 return true;
465 }
466
467 bool ProcessMitigationsWin32KDispatcher::DestroyOPMProtectedOutput(
468 IPCInfo* ipc,
469 void* protected_output) {
470 if (!policy_base_->GetEnableOPMRedirection()) {
471 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
472 return true;
473 }
474 scoped_refptr<ProtectedVideoOutput> output =
475 GetProtectedVideoOutput(protected_output, true);
476 NTSTATUS status = STATUS_INVALID_HANDLE;
477 if (output)
478 status = STATUS_SUCCESS;
479 ipc->return_info.nt_status = status;
480 return true;
481 }
482
483 bool ProcessMitigationsWin32KDispatcher::GetOPMRandomNumber(
484 IPCInfo* ipc,
485 void* protected_output,
486 CountedBuffer* random_number) {
487 if (!policy_base_->GetEnableOPMRedirection()) {
488 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
489 return true;
490 }
491 scoped_refptr<ProtectedVideoOutput> output =
492 GetProtectedVideoOutput(protected_output, false);
493 NTSTATUS status = STATUS_INVALID_PARAMETER;
494 if (!output || random_number->Size() != sizeof(DXGKMDT_OPM_RANDOM_NUMBER)) {
495 status = STATUS_INVALID_PARAMETER;
496 } else {
497 status = ProcessMitigationsWin32KLockdownPolicy::GetOPMRandomNumberAction(
498 *ipc->client_info, output.get()->handle(), random_number->Buffer());
499 }
500 ipc->return_info.nt_status = status;
501 return true;
502 }
503
504 bool ProcessMitigationsWin32KDispatcher::SetOPMSigningKeyAndSequenceNumbers(
505 IPCInfo* ipc,
506 void* protected_output,
507 CountedBuffer* parameters) {
508 if (!policy_base_->GetEnableOPMRedirection()) {
509 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
510 return true;
511 }
512 scoped_refptr<ProtectedVideoOutput> output =
513 GetProtectedVideoOutput(protected_output, false);
514 NTSTATUS status = STATUS_INVALID_PARAMETER;
515 if (!output ||
516 parameters->Size() != sizeof(DXGKMDT_OPM_ENCRYPTED_PARAMETERS)) {
517 status = STATUS_INVALID_PARAMETER;
518 } else {
519 status = ProcessMitigationsWin32KLockdownPolicy::
520 SetOPMSigningKeyAndSequenceNumbersAction(
521 *ipc->client_info, output.get()->handle(), parameters->Buffer());
522 }
523 ipc->return_info.nt_status = status;
524 return true;
525 }
526
527 bool ProcessMitigationsWin32KDispatcher::ConfigureOPMProtectedOutput(
528 IPCInfo* ipc,
529 void* protected_output,
530 void* shared_buffer_handle) {
531 if (!policy_base_->GetEnableOPMRedirection()) {
532 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
533 return true;
534 }
535 scoped_refptr<ProtectedVideoOutput> output =
536 GetProtectedVideoOutput(protected_output, false);
537 if (!output) {
538 ipc->return_info.nt_status = STATUS_INVALID_HANDLE;
539 return true;
540 };
541 base::SharedMemoryHandle handle =
542 GetSharedMemoryHandle(*ipc->client_info, shared_buffer_handle);
543 if (!handle.IsValid()) {
544 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
545 return true;
546 }
547 base::SharedMemory buffer(handle, false);
548 if (!buffer.Map(sizeof(DXGKMDT_OPM_CONFIGURE_PARAMETERS))) {
549 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
550 return true;
551 }
552 NTSTATUS status =
553 ProcessMitigationsWin32KLockdownPolicy::ConfigureOPMProtectedOutputAction(
554 *ipc->client_info, output.get()->handle(), buffer.memory());
555 ipc->return_info.nt_status = status;
556 return true;
557 }
558
559 bool ProcessMitigationsWin32KDispatcher::GetOPMInformation(
560 IPCInfo* ipc,
561 void* protected_output,
562 void* shared_buffer_handle) {
563 if (!policy_base_->GetEnableOPMRedirection()) {
564 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
565 return true;
566 }
567 scoped_refptr<ProtectedVideoOutput> output =
568 GetProtectedVideoOutput(protected_output, false);
569 if (!output) {
570 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
571 return true;
572 }
573 base::SharedMemoryHandle handle =
574 GetSharedMemoryHandle(*ipc->client_info, shared_buffer_handle);
575 if (!handle.IsValid()) {
576 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
577 return true;
578 }
579 base::SharedMemory buffer(handle, false);
580
581 size_t shared_buffer_size =
582 std::max(sizeof(DXGKMDT_OPM_GET_INFO_PARAMETERS),
583 sizeof(DXGKMDT_OPM_REQUESTED_INFORMATION));
584 if (!buffer.Map(shared_buffer_size)) {
585 ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
586 return true;
587 }
588 DXGKMDT_OPM_REQUESTED_INFORMATION requested_info = {};
589 NTSTATUS status =
590 ProcessMitigationsWin32KLockdownPolicy::GetOPMInformationAction(
591 *ipc->client_info, output.get()->handle(), buffer.memory(),
592 &requested_info);
593 if (!status) {
594 memcpy(buffer.memory(), &requested_info,
595 sizeof(DXGKMDT_OPM_REQUESTED_INFORMATION));
596 }
597 ipc->return_info.nt_status = status;
598 return true;
599 }
600
56 } // namespace sandbox 601 } // namespace sandbox
57 602
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698