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

Side by Side Diff: sandbox/win/src/process_mitigations_win32k_unittest.cc

Issue 2944493002: [Windows Sandbox Tests] Process Mitigations. (Closed)
Patch Set: Code review fixes, part 2. Created 3 years, 5 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
(Empty)
1 // Copyright 2017 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
5 #include "sandbox/win/src/process_mitigations.h"
6
7 #include <windows.h>
8
9 #include <d3d9.h>
10 #include <initguid.h>
11 #include <opmapi.h>
12
13 #include "base/strings/stringprintf.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/win/windows_version.h"
16 #include "sandbox/win/src/nt_internals.h"
17 #include "sandbox/win/src/process_mitigations_win32k_policy.h"
18 #include "sandbox/win/tests/common/controller.h"
19 #include "sandbox/win/tests/integration_tests/integration_tests_common.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace {
23
24 //------------------------------------------------------------------------------
25 // Internal Functions
26 //------------------------------------------------------------------------------
27
28 BOOL CALLBACK MonitorEnumCallback(HMONITOR monitor,
29 HDC hdc_monitor,
30 LPRECT rect_monitor,
31 LPARAM data) {
32 std::map<HMONITOR, base::string16>& monitors =
33 *reinterpret_cast<std::map<HMONITOR, base::string16>*>(data);
34 MONITORINFOEXW monitor_info = {};
35 monitor_info.cbSize = sizeof(monitor_info);
36
37 if (!::GetMonitorInfoW(monitor,
38 reinterpret_cast<MONITORINFO*>(&monitor_info)))
39 return FALSE;
40 monitors[monitor] = monitor_info.szDevice;
41 return TRUE;
42 }
43
44 std::map<HMONITOR, base::string16> EnumerateMonitors() {
45 std::map<HMONITOR, base::string16> result;
46 ::EnumDisplayMonitors(nullptr, nullptr, MonitorEnumCallback,
47 reinterpret_cast<LPARAM>(&result));
48 return result;
49 }
50
51 #define HMONITOR_ENTRY(monitor) \
52 result[reinterpret_cast<HMONITOR>(monitor)] = \
53 base::StringPrintf(L"\\\\.\\DISPLAY%X", monitor)
54
55 std::map<HMONITOR, base::string16> GetTestMonitors() {
56 std::map<HMONITOR, base::string16> result;
57
58 HMONITOR_ENTRY(0x11111111);
59 HMONITOR_ENTRY(0x22222222);
60 HMONITOR_ENTRY(0x44444444);
61 HMONITOR_ENTRY(0x88888888);
62 return result;
63 }
64
65 base::string16 UnicodeStringToString(PUNICODE_STRING name) {
66 return base::string16(
67 name->Buffer, name->Buffer + (name->Length / sizeof(name->Buffer[0])));
68 }
69
70 // Returns an index 1, 2, 4 or 8 depening on the device. 0 on error.
71 DWORD GetTestDeviceMonitorIndex(PUNICODE_STRING device_name) {
72 base::string16 name = UnicodeStringToString(device_name);
73 std::map<HMONITOR, base::string16> monitors = GetTestMonitors();
74 for (const auto& monitor : monitors) {
75 if (name == monitor.second)
76 return static_cast<DWORD>(reinterpret_cast<uintptr_t>(monitor.first)) &
77 0xF;
78 }
79 return 0;
80 }
81
82 NTSTATUS WINAPI GetSuggestedOPMProtectedOutputArraySizeTest(
83 PUNICODE_STRING device_name,
84 DWORD* suggested_output_array_size) {
85 DWORD monitor = GetTestDeviceMonitorIndex(device_name);
86 if (!monitor)
87 return STATUS_OBJECT_NAME_NOT_FOUND;
88 *suggested_output_array_size = monitor;
89 return STATUS_SUCCESS;
90 }
91
92 NTSTATUS WINAPI
93 CreateOPMProtectedOutputsTest(PUNICODE_STRING device_name,
94 DXGKMDT_OPM_VIDEO_OUTPUT_SEMANTICS vos,
95 DWORD output_array_size,
96 DWORD* num_in_output_array,
97 OPM_PROTECTED_OUTPUT_HANDLE* output_array) {
98 DWORD monitor = GetTestDeviceMonitorIndex(device_name);
99 if (!monitor)
100 return STATUS_OBJECT_NAME_NOT_FOUND;
101 if (vos != DXGKMDT_OPM_VOS_OPM_SEMANTICS)
102 return STATUS_INVALID_PARAMETER;
103 if (output_array_size != monitor)
104 return STATUS_INVALID_PARAMETER;
105 *num_in_output_array = monitor - 1;
106 for (DWORD index = 0; index < monitor - 1; ++index) {
107 output_array[index] =
108 reinterpret_cast<OPM_PROTECTED_OUTPUT_HANDLE>((monitor << 4) + index);
109 }
110 return STATUS_SUCCESS;
111 }
112
113 ULONG CalculateCertLength(ULONG monitor) {
114 return (monitor * 0x800) + 0xabc;
115 }
116
117 NTSTATUS WINAPI GetCertificateTest(PUNICODE_STRING device_name,
118 DXGKMDT_CERTIFICATE_TYPE certificate_type,
119 BYTE* certificate,
120 ULONG certificate_length) {
121 DWORD monitor = GetTestDeviceMonitorIndex(device_name);
122 if (!monitor)
123 return STATUS_OBJECT_NAME_NOT_FOUND;
124 if (certificate_type != DXGKMDT_OPM_CERTIFICATE)
125 return STATUS_INVALID_PARAMETER;
126 if (certificate_length != CalculateCertLength(monitor))
127 return STATUS_INVALID_PARAMETER;
128 memset(certificate, 'A' + monitor, certificate_length);
129 return STATUS_SUCCESS;
130 }
131
132 NTSTATUS WINAPI
133 GetCertificateSizeTest(PUNICODE_STRING device_name,
134 DXGKMDT_CERTIFICATE_TYPE certificate_type,
135 ULONG* certificate_length) {
136 DWORD monitor = GetTestDeviceMonitorIndex(device_name);
137 if (!monitor)
138 return STATUS_OBJECT_NAME_NOT_FOUND;
139 if (certificate_type != DXGKMDT_OPM_CERTIFICATE)
140 return STATUS_INVALID_PARAMETER;
141 *certificate_length = CalculateCertLength(monitor);
142 return STATUS_SUCCESS;
143 }
144
145 // Check for valid output handle and return the monitor index.
146 DWORD IsValidProtectedOutput(OPM_PROTECTED_OUTPUT_HANDLE protected_output) {
147 uintptr_t handle = reinterpret_cast<uintptr_t>(protected_output);
148 uintptr_t monitor = handle >> 4;
149 uintptr_t index = handle & 0xF;
150 switch (monitor) {
151 case 1:
152 case 2:
153 case 4:
154 case 8:
155 break;
156 default:
157 return 0;
158 }
159 if (index >= (monitor - 1))
160 return 0;
161 return static_cast<DWORD>(monitor);
162 }
163
164 NTSTATUS WINAPI
165 GetCertificateByHandleTest(OPM_PROTECTED_OUTPUT_HANDLE protected_output,
166 DXGKMDT_CERTIFICATE_TYPE certificate_type,
167 BYTE* certificate,
168 ULONG certificate_length) {
169 DWORD monitor = IsValidProtectedOutput(protected_output);
170 if (!monitor)
171 return STATUS_INVALID_HANDLE;
172 if (certificate_type != DXGKMDT_OPM_CERTIFICATE)
173 return STATUS_INVALID_PARAMETER;
174 if (certificate_length != CalculateCertLength(monitor))
175 return STATUS_INVALID_PARAMETER;
176 memset(certificate, 'A' + monitor, certificate_length);
177 return STATUS_SUCCESS;
178 }
179
180 NTSTATUS WINAPI
181 GetCertificateSizeByHandleTest(OPM_PROTECTED_OUTPUT_HANDLE protected_output,
182 DXGKMDT_CERTIFICATE_TYPE certificate_type,
183 ULONG* certificate_length) {
184 DWORD monitor = IsValidProtectedOutput(protected_output);
185 if (!monitor)
186 return STATUS_INVALID_HANDLE;
187 if (certificate_type != DXGKMDT_OPM_CERTIFICATE)
188 return STATUS_INVALID_PARAMETER;
189 *certificate_length = CalculateCertLength(monitor);
190 return STATUS_SUCCESS;
191 }
192
193 NTSTATUS WINAPI
194 DestroyOPMProtectedOutputTest(OPM_PROTECTED_OUTPUT_HANDLE protected_output) {
195 if (!IsValidProtectedOutput(protected_output))
196 return STATUS_INVALID_HANDLE;
197 return STATUS_SUCCESS;
198 }
199
200 NTSTATUS WINAPI ConfigureOPMProtectedOutputTest(
201 OPM_PROTECTED_OUTPUT_HANDLE protected_output,
202 const DXGKMDT_OPM_CONFIGURE_PARAMETERS* parameters,
203 ULONG additional_parameters_size,
204 const BYTE* additional_parameters) {
205 if (!IsValidProtectedOutput(protected_output))
206 return STATUS_INVALID_HANDLE;
207 if (additional_parameters && additional_parameters_size)
208 return STATUS_INVALID_PARAMETER;
209 return STATUS_SUCCESS;
210 }
211
212 NTSTATUS WINAPI GetOPMInformationTest(
213 OPM_PROTECTED_OUTPUT_HANDLE protected_output,
214 const DXGKMDT_OPM_GET_INFO_PARAMETERS* parameters,
215 DXGKMDT_OPM_REQUESTED_INFORMATION* requested_information) {
216 DWORD monitor = IsValidProtectedOutput(protected_output);
217 if (!monitor)
218 return STATUS_INVALID_HANDLE;
219 memset(requested_information, '0' + monitor,
220 sizeof(DXGKMDT_OPM_REQUESTED_INFORMATION));
221 return STATUS_SUCCESS;
222 }
223
224 NTSTATUS WINAPI
225 GetOPMRandomNumberTest(OPM_PROTECTED_OUTPUT_HANDLE protected_output,
226 DXGKMDT_OPM_RANDOM_NUMBER* random_number) {
227 DWORD monitor = IsValidProtectedOutput(protected_output);
228 if (!monitor)
229 return STATUS_INVALID_HANDLE;
230 memset(random_number->abRandomNumber, '!' + monitor,
231 sizeof(random_number->abRandomNumber));
232 return STATUS_SUCCESS;
233 }
234
235 NTSTATUS WINAPI SetOPMSigningKeyAndSequenceNumbersTest(
236 OPM_PROTECTED_OUTPUT_HANDLE protected_output,
237 const DXGKMDT_OPM_ENCRYPTED_PARAMETERS* parameters) {
238 DWORD monitor = IsValidProtectedOutput(protected_output);
239 if (!monitor)
240 return STATUS_INVALID_HANDLE;
241 DXGKMDT_OPM_ENCRYPTED_PARAMETERS test_params = {};
242 memset(test_params.abEncryptedParameters, 'a' + monitor,
243 sizeof(test_params.abEncryptedParameters));
244 if (memcmp(test_params.abEncryptedParameters,
245 parameters->abEncryptedParameters,
246 sizeof(test_params.abEncryptedParameters)) != 0)
247 return STATUS_INVALID_PARAMETER;
248 return STATUS_SUCCESS;
249 }
250
251 BOOL WINAPI EnumDisplayMonitorsTest(HDC hdc,
252 LPCRECT clip_rect,
253 MONITORENUMPROC enum_function,
254 LPARAM data) {
255 RECT rc = {};
256 for (const auto& monitor : GetTestMonitors()) {
257 if (!enum_function(monitor.first, hdc, &rc, data))
258 return FALSE;
259 }
260 return TRUE;
261 }
262
263 BOOL WINAPI GetMonitorInfoWTest(HMONITOR monitor, LPMONITORINFO monitor_info) {
264 std::map<HMONITOR, base::string16> monitors = GetTestMonitors();
265 if (monitor_info->cbSize != sizeof(MONITORINFO) &&
266 monitor_info->cbSize != sizeof(MONITORINFOEXW))
267 return FALSE;
268 auto it = monitors.find(monitor);
269 if (it == monitors.end())
270 return FALSE;
271 if (monitor_info->cbSize == sizeof(MONITORINFOEXW)) {
272 MONITORINFOEXW* monitor_info_ex =
273 reinterpret_cast<MONITORINFOEXW*>(monitor_info);
274 size_t copy_size = (it->second.size() + 1) * sizeof(WCHAR);
275 if (copy_size > sizeof(monitor_info_ex->szDevice) - sizeof(WCHAR))
276 copy_size = sizeof(monitor_info_ex->szDevice) - sizeof(WCHAR);
277 memset(monitor_info_ex->szDevice, 0, sizeof(monitor_info_ex->szDevice));
278 memcpy(monitor_info_ex->szDevice, it->second.c_str(), copy_size);
279 }
280 return TRUE;
281 }
282
283 #define RETURN_TEST_FUNC(n) \
284 if (strcmp(name, #n) == 0) { \
285 return n##Test; \
286 }
287
288 void* FunctionOverrideForTest(const char* name) {
289 RETURN_TEST_FUNC(GetSuggestedOPMProtectedOutputArraySize);
290 RETURN_TEST_FUNC(CreateOPMProtectedOutputs);
291 RETURN_TEST_FUNC(GetCertificate);
292 RETURN_TEST_FUNC(GetCertificateSize);
293 RETURN_TEST_FUNC(DestroyOPMProtectedOutput);
294 RETURN_TEST_FUNC(ConfigureOPMProtectedOutput);
295 RETURN_TEST_FUNC(GetOPMInformation);
296 RETURN_TEST_FUNC(GetOPMRandomNumber);
297 RETURN_TEST_FUNC(SetOPMSigningKeyAndSequenceNumbers);
298 RETURN_TEST_FUNC(EnumDisplayMonitors);
299 RETURN_TEST_FUNC(GetMonitorInfoW);
300 RETURN_TEST_FUNC(GetCertificateByHandle);
301 RETURN_TEST_FUNC(GetCertificateSizeByHandle);
302 NOTREACHED();
303 return nullptr;
304 }
305
306 bool RunTestsOnVideoOutputConfigure(uintptr_t monitor_index,
307 IOPMVideoOutput* video_output) {
308 OPM_CONFIGURE_PARAMETERS config_params = {};
309 OPM_SET_PROTECTION_LEVEL_PARAMETERS* protection_level =
310 reinterpret_cast<OPM_SET_PROTECTION_LEVEL_PARAMETERS*>(
311 config_params.abParameters);
312 protection_level->ulProtectionType = OPM_PROTECTION_TYPE_HDCP;
313 protection_level->ulProtectionLevel = OPM_HDCP_ON;
314 config_params.guidSetting = OPM_SET_PROTECTION_LEVEL;
315 config_params.cbParametersSize = sizeof(OPM_SET_PROTECTION_LEVEL_PARAMETERS);
316 HRESULT hr = video_output->Configure(&config_params, 0, nullptr);
317 if (FAILED(hr))
318 return false;
319 protection_level->ulProtectionType = OPM_PROTECTION_TYPE_DPCP;
320 hr = video_output->Configure(&config_params, 0, nullptr);
321 if (FAILED(hr))
322 return false;
323 protection_level->ulProtectionLevel = OPM_HDCP_OFF;
324 hr = video_output->Configure(&config_params, 0, nullptr);
325 if (FAILED(hr))
326 return false;
327 BYTE dummy_byte = 0;
328 hr = video_output->Configure(&config_params, 1, &dummy_byte);
329 if (SUCCEEDED(hr))
330 return false;
331 protection_level->ulProtectionType = 0xFFFFFFFF;
332 hr = video_output->Configure(&config_params, 0, nullptr);
333 if (SUCCEEDED(hr))
334 return false;
335 // Invalid protection level test.
336 protection_level->ulProtectionType = OPM_PROTECTION_TYPE_HDCP;
337 protection_level->ulProtectionLevel = OPM_HDCP_ON + 1;
338 hr = video_output->Configure(&config_params, 0, nullptr);
339 if (SUCCEEDED(hr))
340 return false;
341 hr = video_output->Configure(&config_params, 0, nullptr);
342 if (SUCCEEDED(hr))
343 return false;
344 config_params.guidSetting = OPM_SET_HDCP_SRM;
345 OPM_SET_HDCP_SRM_PARAMETERS* srm_parameters =
346 reinterpret_cast<OPM_SET_HDCP_SRM_PARAMETERS*>(
347 config_params.abParameters);
348 srm_parameters->ulSRMVersion = 1;
349 config_params.cbParametersSize = sizeof(OPM_SET_HDCP_SRM_PARAMETERS);
350 hr = video_output->Configure(&config_params, 0, nullptr);
351 if (SUCCEEDED(hr))
352 return false;
353 return true;
354 }
355
356 bool RunTestsOnVideoOutputFinishInitialization(uintptr_t monitor_index,
357 IOPMVideoOutput* video_output) {
358 OPM_ENCRYPTED_INITIALIZATION_PARAMETERS init_params = {};
359 memset(init_params.abEncryptedInitializationParameters, 'a' + monitor_index,
360 sizeof(init_params.abEncryptedInitializationParameters));
361 HRESULT hr = video_output->FinishInitialization(&init_params);
362 if (FAILED(hr))
363 return false;
364 memset(init_params.abEncryptedInitializationParameters, 'Z' + monitor_index,
365 sizeof(init_params.abEncryptedInitializationParameters));
366 hr = video_output->FinishInitialization(&init_params);
367 if (SUCCEEDED(hr))
368 return false;
369 return true;
370 }
371
372 bool RunTestsOnVideoOutputStartInitialization(uintptr_t monitor_index,
373 IOPMVideoOutput* video_output) {
374 OPM_RANDOM_NUMBER random_number = {};
375 BYTE* certificate = nullptr;
376 ULONG certificate_length = 0;
377
378 HRESULT hr = video_output->StartInitialization(&random_number, &certificate,
379 &certificate_length);
380 if (FAILED(hr))
381 return false;
382
383 if (certificate_length != CalculateCertLength(monitor_index))
384 return false;
385
386 for (ULONG i = 0; i < certificate_length; ++i) {
387 if (certificate[i] != 'A' + monitor_index)
388 return false;
389 }
390
391 for (ULONG i = 0; i < sizeof(random_number.abRandomNumber); ++i) {
392 if (random_number.abRandomNumber[i] != '!' + monitor_index)
393 return false;
394 }
395
396 return true;
397 }
398
399 static bool SendSingleGetInfoRequest(uintptr_t monitor_index,
400 IOPMVideoOutput* video_output,
401 const GUID& request,
402 ULONG data_length,
403 void* data) {
404 OPM_GET_INFO_PARAMETERS params = {};
405 OPM_REQUESTED_INFORMATION requested_information = {};
406 BYTE* requested_information_ptr =
407 reinterpret_cast<BYTE*>(&requested_information);
408 params.guidInformation = request;
409 params.cbParametersSize = data_length;
410 memcpy(params.abParameters, data, data_length);
411 HRESULT hr = video_output->GetInformation(&params, &requested_information);
412 if (FAILED(hr))
413 return false;
414 for (size_t i = 0; i < sizeof(OPM_REQUESTED_INFORMATION); ++i) {
415 if (requested_information_ptr[i] != '0' + monitor_index)
416 return false;
417 }
418 return true;
419 }
420
421 bool RunTestsOnVideoOutputGetInformation(uintptr_t monitor_index,
422 IOPMVideoOutput* video_output) {
423 ULONG dummy = 0;
424 if (!SendSingleGetInfoRequest(monitor_index, video_output,
425 OPM_GET_CONNECTOR_TYPE, 0, nullptr)) {
426 return false;
427 }
428 if (!SendSingleGetInfoRequest(monitor_index, video_output,
429 OPM_GET_SUPPORTED_PROTECTION_TYPES, 0,
430 nullptr)) {
431 return false;
432 }
433 // These should fail due to invalid parameter sizes.
434 if (SendSingleGetInfoRequest(monitor_index, video_output,
435 OPM_GET_CONNECTOR_TYPE, sizeof(dummy), &dummy)) {
436 return false;
437 }
438 if (SendSingleGetInfoRequest(monitor_index, video_output,
439 OPM_GET_SUPPORTED_PROTECTION_TYPES,
440 sizeof(dummy), &dummy)) {
441 return false;
442 }
443 ULONG protection_type = OPM_PROTECTION_TYPE_HDCP;
444 if (!SendSingleGetInfoRequest(monitor_index, video_output,
445 OPM_GET_ACTUAL_PROTECTION_LEVEL,
446 sizeof(protection_type), &protection_type)) {
447 return false;
448 }
449 protection_type = OPM_PROTECTION_TYPE_DPCP;
450 if (!SendSingleGetInfoRequest(monitor_index, video_output,
451 OPM_GET_ACTUAL_PROTECTION_LEVEL,
452 sizeof(protection_type), &protection_type)) {
453 return false;
454 }
455 // These should fail as unsupported or invalid parameters.
456 protection_type = OPM_PROTECTION_TYPE_ACP;
457 if (SendSingleGetInfoRequest(monitor_index, video_output,
458 OPM_GET_ACTUAL_PROTECTION_LEVEL,
459 sizeof(protection_type), &protection_type)) {
460 return false;
461 }
462 if (SendSingleGetInfoRequest(monitor_index, video_output,
463 OPM_GET_ACTUAL_PROTECTION_LEVEL, 0, nullptr)) {
464 return false;
465 }
466 protection_type = OPM_PROTECTION_TYPE_HDCP;
467 if (!SendSingleGetInfoRequest(monitor_index, video_output,
468 OPM_GET_VIRTUAL_PROTECTION_LEVEL,
469 sizeof(protection_type), &protection_type)) {
470 return false;
471 }
472 protection_type = OPM_PROTECTION_TYPE_DPCP;
473 if (!SendSingleGetInfoRequest(monitor_index, video_output,
474 OPM_GET_VIRTUAL_PROTECTION_LEVEL,
475 sizeof(protection_type), &protection_type)) {
476 return false;
477 }
478 // These should fail as unsupported or invalid parameters.
479 protection_type = OPM_PROTECTION_TYPE_ACP;
480 if (SendSingleGetInfoRequest(monitor_index, video_output,
481 OPM_GET_VIRTUAL_PROTECTION_LEVEL,
482 sizeof(protection_type), &protection_type)) {
483 return false;
484 }
485 if (SendSingleGetInfoRequest(monitor_index, video_output,
486 OPM_GET_VIRTUAL_PROTECTION_LEVEL, 0, nullptr)) {
487 return false;
488 }
489 // This should fail with unsupported request.
490 if (SendSingleGetInfoRequest(monitor_index, video_output, OPM_GET_CODEC_INFO,
491 0, nullptr)) {
492 return false;
493 }
494 return true;
495 }
496
497 int RunTestsOnVideoOutput(uintptr_t monitor_index,
498 IOPMVideoOutput* video_output) {
499 if (!RunTestsOnVideoOutputStartInitialization(monitor_index, video_output))
500 return sandbox::SBOX_TEST_FIRST_ERROR;
501
502 if (!RunTestsOnVideoOutputFinishInitialization(monitor_index, video_output))
503 return sandbox::SBOX_TEST_SECOND_ERROR;
504
505 if (!RunTestsOnVideoOutputConfigure(monitor_index, video_output))
506 return sandbox::SBOX_TEST_THIRD_ERROR;
507
508 if (!RunTestsOnVideoOutputGetInformation(monitor_index, video_output))
509 return sandbox::SBOX_TEST_FOURTH_ERROR;
510
511 return sandbox::SBOX_TEST_SUCCEEDED;
512 }
513
514 } // namespace
515
516 namespace sandbox {
517
518 //------------------------------------------------------------------------------
519 // Exported functions called by child test processes.
520 //------------------------------------------------------------------------------
521
522 SBOX_TESTS_COMMAND int CheckWin8MonitorsRedirection(int argc, wchar_t** argv) {
523 std::map<HMONITOR, base::string16> monitors = EnumerateMonitors();
524 std::map<HMONITOR, base::string16> monitors_to_test = GetTestMonitors();
525 if (monitors.size() != monitors_to_test.size())
526 return SBOX_TEST_FIRST_ERROR;
527
528 for (const auto& monitor : monitors) {
529 auto result = monitors_to_test.find(monitor.first);
530 if (result == monitors_to_test.end())
531 return SBOX_TEST_SECOND_ERROR;
532 if (result->second != monitor.second)
533 return SBOX_TEST_THIRD_ERROR;
534 }
535 return SBOX_TEST_SUCCEEDED;
536 }
537
538 SBOX_TESTS_COMMAND int CheckWin8MonitorInfo(int argc, wchar_t** argv) {
539 std::map<HMONITOR, base::string16> monitors_to_test = GetTestMonitors();
540 MONITORINFO monitor_info = {};
541 MONITORINFOEXW monitor_info_exw = {};
542 MONITORINFOEXA monitor_info_exa = {};
543 HMONITOR valid_monitor = monitors_to_test.begin()->first;
544 base::string16 valid_device = monitors_to_test.begin()->second;
545 monitor_info.cbSize = sizeof(MONITORINFO);
546 if (!::GetMonitorInfoW(valid_monitor, &monitor_info))
547 return SBOX_TEST_FIRST_ERROR;
548 monitor_info.cbSize = sizeof(MONITORINFO);
549 if (!::GetMonitorInfoA(valid_monitor, &monitor_info))
550 return SBOX_TEST_SECOND_ERROR;
551 monitor_info_exw.cbSize = sizeof(MONITORINFOEXW);
552 if (!::GetMonitorInfoW(valid_monitor,
553 reinterpret_cast<MONITORINFO*>(&monitor_info_exw)) ||
554 valid_device != monitor_info_exw.szDevice) {
555 return SBOX_TEST_THIRD_ERROR;
556 }
557 monitor_info_exa.cbSize = sizeof(MONITORINFOEXA);
558 if (!::GetMonitorInfoA(valid_monitor,
559 reinterpret_cast<MONITORINFO*>(&monitor_info_exa)) ||
560 valid_device != base::ASCIIToUTF16(monitor_info_exa.szDevice)) {
561 return SBOX_TEST_FOURTH_ERROR;
562 }
563
564 // Invalid size checks.
565 monitor_info.cbSize = 0;
566 if (::GetMonitorInfoW(valid_monitor, &monitor_info))
567 return SBOX_TEST_FIFTH_ERROR;
568 monitor_info.cbSize = 0x10000;
569 if (::GetMonitorInfoW(valid_monitor, &monitor_info))
570 return SBOX_TEST_SIXTH_ERROR;
571
572 // Check that an invalid handle isn't accepted.
573 HMONITOR invalid_monitor = reinterpret_cast<HMONITOR>(-1);
574 monitor_info.cbSize = sizeof(MONITORINFO);
575 if (::GetMonitorInfoW(invalid_monitor, &monitor_info))
576 return SBOX_TEST_SEVENTH_ERROR;
577
578 return SBOX_TEST_SUCCEEDED;
579 }
580
581 SBOX_TESTS_COMMAND int CheckWin8OPMApis(int argc, wchar_t** argv) {
582 std::map<HMONITOR, base::string16> monitors = GetTestMonitors();
583 for (const auto& monitor : monitors) {
584 ULONG output_count = 0;
585 IOPMVideoOutput** outputs = nullptr;
586 uintptr_t monitor_index = reinterpret_cast<uintptr_t>(monitor.first) & 0xF;
587 HRESULT hr = OPMGetVideoOutputsFromHMONITOR(
588 monitor.first, OPM_VOS_OPM_SEMANTICS, &output_count, &outputs);
589 if (monitor_index > 4) {
590 // These should fail because the certificate is too large.
591 if (SUCCEEDED(hr))
592 return SBOX_TEST_FIRST_ERROR;
593 continue;
594 }
595 if (FAILED(hr))
596 return SBOX_TEST_SECOND_ERROR;
597 if (output_count != monitor_index - 1)
598 return SBOX_TEST_THIRD_ERROR;
599 for (ULONG output_index = 0; output_index < output_count; ++output_index) {
600 int result = RunTestsOnVideoOutput(monitor_index, outputs[output_index]);
601 outputs[output_index]->Release();
602 if (result != SBOX_TEST_SUCCEEDED)
603 return result;
604 }
605 ::CoTaskMemFree(outputs);
606 }
607 return SBOX_TEST_SUCCEEDED;
608 }
609
610 //------------------------------------------------------------------------------
611 // Exported Win32k Lockdown Tests
612 //------------------------------------------------------------------------------
613
614 // This test validates that setting the MITIGATION_WIN32K_DISABLE mitigation on
615 // the target process causes the launch to fail in process initialization.
616 // The test process itself links against user32/gdi32.
617 TEST(ProcessMitigationsWin32kTest, CheckWin8LockDownFailure) {
618 if (base::win::GetVersion() < base::win::VERSION_WIN8)
619 return;
620
621 base::string16 test_policy_command = L"CheckPolicy ";
622 test_policy_command += std::to_wstring(TESTPOLICY_WIN32K);
623
624 TestRunner runner;
625 sandbox::TargetPolicy* policy = runner.GetPolicy();
626
627 EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_WIN32K_DISABLE),
628 SBOX_ALL_OK);
629 EXPECT_NE(SBOX_TEST_SUCCEEDED, runner.RunTest(test_policy_command.c_str()));
630 }
631
632 // This test validates that setting the MITIGATION_WIN32K_DISABLE mitigation
633 // along with the policy to fake user32 and gdi32 initialization successfully
634 // launches the target process.
635 // The test process itself links against user32/gdi32.
636 TEST(ProcessMitigationsWin32kTest, CheckWin8LockDownSuccess) {
637 if (base::win::GetVersion() < base::win::VERSION_WIN8)
638 return;
639
640 base::string16 test_policy_command = L"CheckPolicy ";
641 test_policy_command += std::to_wstring(TESTPOLICY_WIN32K);
642
643 TestRunner runner;
644 sandbox::TargetPolicy* policy = runner.GetPolicy();
645 ProcessMitigationsWin32KLockdownPolicy::SetOverrideForTestCallback(
646 FunctionOverrideForTest);
647
648 EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_WIN32K_DISABLE),
649 SBOX_ALL_OK);
650 EXPECT_EQ(policy->AddRule(sandbox::TargetPolicy::SUBSYS_WIN32K_LOCKDOWN,
651 sandbox::TargetPolicy::FAKE_USER_GDI_INIT, NULL),
652 sandbox::SBOX_ALL_OK);
653 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_policy_command.c_str()));
654 EXPECT_NE(SBOX_TEST_SUCCEEDED,
655 runner.RunTest(L"CheckWin8MonitorsRedirection"));
656 EXPECT_NE(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8MonitorInfo"));
657 EXPECT_NE(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8OPMApis"));
658 }
659
660 // This test validates the even though we're running under win32k lockdown
661 // we can use the IPC redirection to enumerate the list of monitors.
662 TEST(ProcessMitigationsWin32kTest, CheckWin8Redirection) {
663 if (base::win::GetVersion() < base::win::VERSION_WIN8)
664 return;
665
666 base::string16 test_policy_command = L"CheckPolicy ";
667 test_policy_command += std::to_wstring(TESTPOLICY_WIN32K);
668
669 TestRunner runner;
670 sandbox::TargetPolicy* policy = runner.GetPolicy();
671 ProcessMitigationsWin32KLockdownPolicy::SetOverrideForTestCallback(
672 FunctionOverrideForTest);
673
674 EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_WIN32K_DISABLE),
675 SBOX_ALL_OK);
676 EXPECT_EQ(policy->AddRule(sandbox::TargetPolicy::SUBSYS_WIN32K_LOCKDOWN,
677 sandbox::TargetPolicy::IMPLEMENT_OPM_APIS, NULL),
678 sandbox::SBOX_ALL_OK);
679 policy->SetEnableOPMRedirection();
680 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_policy_command.c_str()));
681 EXPECT_EQ(SBOX_TEST_SUCCEEDED,
682 runner.RunTest(L"CheckWin8MonitorsRedirection"));
683 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8MonitorInfo"));
684 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8OPMApis"));
685 }
686
687 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/win/src/process_mitigations_unittest.cc ('k') | sandbox/win/tests/integration_tests/hooking_dll.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698