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

Side by Side 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: Add Windows 10 specific hooks 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 (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <initguid.h>
6 #include <d3d9.h>
7 #include <Opmapi.h>
8 #include <windows.h>
9
10 #include <map>
11 #include <string>
12
5 #include "base/files/file_util.h" 13 #include "base/files/file_util.h"
6 #include "base/files/scoped_temp_dir.h" 14 #include "base/files/scoped_temp_dir.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/memory/scoped_ptr.h"
7 #include "base/path_service.h" 17 #include "base/path_service.h"
8 #include "base/process/launch.h" 18 #include "base/process/launch.h"
9 #include "base/strings/stringprintf.h" 19 #include "base/strings/stringprintf.h"
20 #include "base/strings/utf_string_conversions.h"
10 #include "base/win/scoped_handle.h" 21 #include "base/win/scoped_handle.h"
11 #include "base/win/windows_version.h" 22 #include "base/win/windows_version.h"
12 #include "sandbox/win/src/nt_internals.h" 23 #include "sandbox/win/src/nt_internals.h"
13 #include "sandbox/win/src/process_mitigations.h" 24 #include "sandbox/win/src/process_mitigations.h"
25 #include "sandbox/win/src/process_mitigations_win32k_policy.h"
14 #include "sandbox/win/src/sandbox.h" 26 #include "sandbox/win/src/sandbox.h"
15 #include "sandbox/win/src/sandbox_factory.h" 27 #include "sandbox/win/src/sandbox_factory.h"
16 #include "sandbox/win/src/target_services.h" 28 #include "sandbox/win/src/target_services.h"
17 #include "sandbox/win/src/win_utils.h" 29 #include "sandbox/win/src/win_utils.h"
18 #include "sandbox/win/tests/common/controller.h" 30 #include "sandbox/win/tests/common/controller.h"
19 #include "testing/gtest/include/gtest/gtest.h" 31 #include "testing/gtest/include/gtest/gtest.h"
20 32
21 namespace { 33 namespace {
22 34
23 // API defined in winbase.h. 35 // API defined in winbase.h.
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 } 204 }
193 205
194 std::wstring test = L"TestChildProcess "; 206 std::wstring test = L"TestChildProcess ";
195 test += new_path.value().c_str(); 207 test += new_path.value().c_str();
196 208
197 EXPECT_EQ((is_success_test ? sandbox::SBOX_TEST_SUCCEEDED 209 EXPECT_EQ((is_success_test ? sandbox::SBOX_TEST_SUCCEEDED
198 : sandbox::SBOX_TEST_FAILED), 210 : sandbox::SBOX_TEST_FAILED),
199 runner.RunTest(test.c_str())); 211 runner.RunTest(test.c_str()));
200 } 212 }
201 213
214 BOOL CALLBACK MonitorEnumCallback(HMONITOR monitor,
215 HDC hdc_monitor,
216 LPRECT rect_monitor,
217 LPARAM data) {
218 std::map<HMONITOR, base::string16>& monitors =
219 *reinterpret_cast<std::map<HMONITOR, base::string16>*>(data);
220 MONITORINFOEXW monitor_info = {};
221 monitor_info.cbSize = sizeof(monitor_info);
222
223 if (!::GetMonitorInfoW(monitor,
224 reinterpret_cast<MONITORINFO*>(&monitor_info)))
225 return FALSE;
226 monitors[monitor] = monitor_info.szDevice;
227 return TRUE;
228 }
229
230 std::map<HMONITOR, std::wstring> EnumerateMonitors() {
231 std::map<HMONITOR, std::wstring> result;
232 ::EnumDisplayMonitors(nullptr, nullptr, MonitorEnumCallback,
233 reinterpret_cast<LPARAM>(&result));
234 return result;
235 }
236
237 #define HMONITOR_ENTRY(monitor) \
238 result[reinterpret_cast<HMONITOR>(monitor)] = \
239 base::StringPrintf(L"\\\\.\\DISPLAY%X", monitor)
240
241 std::map<HMONITOR, std::wstring> GetTestMonitors() {
242 std::map<HMONITOR, std::wstring> result;
243
244 HMONITOR_ENTRY(0x11111111);
245 HMONITOR_ENTRY(0x22222222);
246 HMONITOR_ENTRY(0x44444444);
247 HMONITOR_ENTRY(0x88888888);
248 return result;
249 }
250
251 std::wstring UnicodeStringToString(PUNICODE_STRING name) {
252 return std::wstring(name->Buffer,
253 name->Buffer + (name->Length / sizeof(name->Buffer[0])));
254 }
255
256 // Returns an index 1, 2, 4 or 8 depening on the device. 0 on error.
257 DWORD GetTestDeviceMonitorIndex(PUNICODE_STRING device_name) {
258 std::wstring name = UnicodeStringToString(device_name);
259 std::map<HMONITOR, std::wstring> monitors = GetTestMonitors();
260 for (const auto& monitor : monitors) {
261 if (name == monitor.second)
262 return static_cast<DWORD>(reinterpret_cast<uintptr_t>(monitor.first)) &
263 0xF;
264 }
265 return 0;
266 }
267
268 NTSTATUS WINAPI GetSuggestedOPMProtectedOutputArraySizeTest(
269 PUNICODE_STRING device_name,
270 DWORD* suggested_output_array_size) {
271 DWORD monitor = GetTestDeviceMonitorIndex(device_name);
272 if (!monitor)
273 return STATUS_OBJECT_NAME_NOT_FOUND;
274 *suggested_output_array_size = monitor;
275 return STATUS_SUCCESS;
276 }
277
278 NTSTATUS WINAPI
279 CreateOPMProtectedOutputsTest(PUNICODE_STRING device_name,
280 DXGKMDT_OPM_VIDEO_OUTPUT_SEMANTICS vos,
281 DWORD output_array_size,
282 DWORD* num_in_output_array,
283 OPM_PROTECTED_OUTPUT_HANDLE* output_array) {
284 DWORD monitor = GetTestDeviceMonitorIndex(device_name);
285 if (!monitor)
286 return STATUS_OBJECT_NAME_NOT_FOUND;
287 if (vos != DXGKMDT_OPM_VOS_OPM_SEMANTICS)
288 return STATUS_INVALID_PARAMETER;
289 if (output_array_size != monitor)
290 return STATUS_INVALID_PARAMETER;
291 *num_in_output_array = monitor - 1;
292 for (DWORD index = 0; index < monitor - 1; ++index) {
293 output_array[index] =
294 reinterpret_cast<OPM_PROTECTED_OUTPUT_HANDLE>((monitor << 4) + index);
295 }
296 return STATUS_SUCCESS;
297 }
298
299 ULONG CalculateCertLength(ULONG monitor) {
300 return (monitor * 0x800) + 0xabc;
301 }
302
303 NTSTATUS WINAPI GetCertificateTest(PUNICODE_STRING device_name,
304 DXGKMDT_CERTIFICATE_TYPE certificate_type,
305 BYTE* certificate,
306 ULONG certificate_length) {
307 DWORD monitor = GetTestDeviceMonitorIndex(device_name);
308 if (!monitor)
309 return STATUS_OBJECT_NAME_NOT_FOUND;
310 if (certificate_type != DXGKMDT_OPM_CERTIFICATE)
311 return STATUS_INVALID_PARAMETER;
312 if (certificate_length != CalculateCertLength(monitor))
313 return STATUS_INVALID_PARAMETER;
314 memset(certificate, 'A' + monitor, certificate_length);
315 return STATUS_SUCCESS;
316 }
317
318 NTSTATUS WINAPI
319 GetCertificateSizeTest(PUNICODE_STRING device_name,
320 DXGKMDT_CERTIFICATE_TYPE certificate_type,
321 ULONG* certificate_length) {
322 DWORD monitor = GetTestDeviceMonitorIndex(device_name);
323 if (!monitor)
324 return STATUS_OBJECT_NAME_NOT_FOUND;
325 if (certificate_type != DXGKMDT_OPM_CERTIFICATE)
326 return STATUS_INVALID_PARAMETER;
327 *certificate_length = CalculateCertLength(monitor);
328 return STATUS_SUCCESS;
329 }
330
331 // Check for valid output handle and return the monitor index.
332 DWORD IsValidProtectedOutput(OPM_PROTECTED_OUTPUT_HANDLE protected_output) {
333 uintptr_t handle = reinterpret_cast<uintptr_t>(protected_output);
334 uintptr_t monitor = handle >> 4;
335 uintptr_t index = handle & 0xF;
336 switch (monitor) {
337 case 1:
338 case 2:
339 case 4:
340 case 8:
341 break;
342 default:
343 return 0;
344 }
345 if (index >= (monitor - 1))
346 return 0;
347 return static_cast<DWORD>(monitor);
348 }
349
350 NTSTATUS WINAPI
351 GetCertificateByHandleTest(OPM_PROTECTED_OUTPUT_HANDLE protected_output,
352 DXGKMDT_CERTIFICATE_TYPE certificate_type,
353 BYTE* certificate,
354 ULONG certificate_length) {
355 DWORD monitor = IsValidProtectedOutput(protected_output);
356 if (!monitor)
357 return STATUS_INVALID_HANDLE;
358 if (certificate_type != DXGKMDT_OPM_CERTIFICATE)
359 return STATUS_INVALID_PARAMETER;
360 if (certificate_length != CalculateCertLength(monitor))
361 return STATUS_INVALID_PARAMETER;
362 memset(certificate, 'A' + monitor, certificate_length);
363 return STATUS_SUCCESS;
364 }
365
366 NTSTATUS WINAPI
367 GetCertificateSizeByHandleTest(OPM_PROTECTED_OUTPUT_HANDLE protected_output,
368 DXGKMDT_CERTIFICATE_TYPE certificate_type,
369 ULONG* certificate_length) {
370 DWORD monitor = IsValidProtectedOutput(protected_output);
371 if (!monitor)
372 return STATUS_INVALID_HANDLE;
373 if (certificate_type != DXGKMDT_OPM_CERTIFICATE)
374 return STATUS_INVALID_PARAMETER;
375 *certificate_length = CalculateCertLength(monitor);
376 return STATUS_SUCCESS;
377 }
378
379 NTSTATUS WINAPI
380 DestroyOPMProtectedOutputTest(OPM_PROTECTED_OUTPUT_HANDLE protected_output) {
381 if (!IsValidProtectedOutput(protected_output))
382 return STATUS_INVALID_HANDLE;
383 return STATUS_SUCCESS;
384 }
385
386 NTSTATUS WINAPI ConfigureOPMProtectedOutputTest(
387 OPM_PROTECTED_OUTPUT_HANDLE protected_output,
388 const DXGKMDT_OPM_CONFIGURE_PARAMETERS* parameters,
389 ULONG additional_parameters_size,
390 const BYTE* additional_parameters) {
391 if (!IsValidProtectedOutput(protected_output))
392 return STATUS_INVALID_HANDLE;
393 if (additional_parameters && additional_parameters_size)
394 return STATUS_INVALID_PARAMETER;
395 return STATUS_SUCCESS;
396 }
397
398 NTSTATUS WINAPI GetOPMInformationTest(
399 OPM_PROTECTED_OUTPUT_HANDLE protected_output,
400 const DXGKMDT_OPM_GET_INFO_PARAMETERS* parameters,
401 DXGKMDT_OPM_REQUESTED_INFORMATION* requested_information) {
402 DWORD monitor = IsValidProtectedOutput(protected_output);
403 if (!monitor)
404 return STATUS_INVALID_HANDLE;
405 memset(requested_information, '0' + monitor,
406 sizeof(DXGKMDT_OPM_REQUESTED_INFORMATION));
407 return STATUS_SUCCESS;
408 }
409
410 NTSTATUS WINAPI
411 GetOPMRandomNumberTest(OPM_PROTECTED_OUTPUT_HANDLE protected_output,
412 DXGKMDT_OPM_RANDOM_NUMBER* random_number) {
413 DWORD monitor = IsValidProtectedOutput(protected_output);
414 if (!monitor)
415 return STATUS_INVALID_HANDLE;
416 memset(random_number->abRandomNumber, '!' + monitor,
417 sizeof(random_number->abRandomNumber));
418 return STATUS_SUCCESS;
419 }
420
421 NTSTATUS WINAPI SetOPMSigningKeyAndSequenceNumbersTest(
422 OPM_PROTECTED_OUTPUT_HANDLE protected_output,
423 const DXGKMDT_OPM_ENCRYPTED_PARAMETERS* parameters) {
424 DWORD monitor = IsValidProtectedOutput(protected_output);
425 if (!monitor)
426 return STATUS_INVALID_HANDLE;
427 DXGKMDT_OPM_ENCRYPTED_PARAMETERS test_params = {};
428 memset(test_params.abEncryptedParameters, 'a' + monitor,
429 sizeof(test_params.abEncryptedParameters));
430 if (memcmp(test_params.abEncryptedParameters,
431 parameters->abEncryptedParameters,
432 sizeof(test_params.abEncryptedParameters)) != 0)
433 return STATUS_INVALID_PARAMETER;
434 return STATUS_SUCCESS;
435 }
436
437 BOOL WINAPI EnumDisplayMonitorsTest(HDC hdc,
438 LPCRECT clip_rect,
439 MONITORENUMPROC enum_function,
440 LPARAM data) {
441 RECT rc = {};
442 for (const auto& monitor : GetTestMonitors()) {
443 if (!enum_function(monitor.first, hdc, &rc, data))
444 return FALSE;
445 }
446 return TRUE;
447 }
448
449 BOOL WINAPI GetMonitorInfoWTest(HMONITOR monitor, LPMONITORINFO monitor_info) {
450 std::map<HMONITOR, std::wstring> monitors = GetTestMonitors();
451 if (monitor_info->cbSize != sizeof(MONITORINFO) &&
452 monitor_info->cbSize != sizeof(MONITORINFOEXW))
453 return FALSE;
454 auto it = monitors.find(monitor);
455 if (it == monitors.end())
456 return FALSE;
457 if (monitor_info->cbSize == sizeof(MONITORINFOEXW)) {
458 MONITORINFOEXW* monitor_info_ex =
459 reinterpret_cast<MONITORINFOEXW*>(monitor_info);
460 size_t copy_size = (it->second.size() + 1) * sizeof(WCHAR);
461 if (copy_size > sizeof(monitor_info_ex->szDevice) - sizeof(WCHAR))
462 copy_size = sizeof(monitor_info_ex->szDevice) - sizeof(WCHAR);
463 memset(monitor_info_ex->szDevice, 0, sizeof(monitor_info_ex->szDevice));
464 memcpy(monitor_info_ex->szDevice, it->second.c_str(), copy_size);
465 }
466 return TRUE;
467 }
468
469 #define RETURN_TEST_FUNC(n) \
470 if (strcmp(name, #n) == 0) { \
471 return n##Test; \
472 }
473
474 void* FunctionOverrideForTest(const char* name) {
475 RETURN_TEST_FUNC(GetSuggestedOPMProtectedOutputArraySize);
476 RETURN_TEST_FUNC(CreateOPMProtectedOutputs);
477 RETURN_TEST_FUNC(GetCertificate);
478 RETURN_TEST_FUNC(GetCertificateSize);
479 RETURN_TEST_FUNC(DestroyOPMProtectedOutput);
480 RETURN_TEST_FUNC(ConfigureOPMProtectedOutput);
481 RETURN_TEST_FUNC(GetOPMInformation);
482 RETURN_TEST_FUNC(GetOPMRandomNumber);
483 RETURN_TEST_FUNC(SetOPMSigningKeyAndSequenceNumbers);
484 RETURN_TEST_FUNC(EnumDisplayMonitors);
485 RETURN_TEST_FUNC(GetMonitorInfoW);
486 RETURN_TEST_FUNC(GetCertificateByHandle);
487 RETURN_TEST_FUNC(GetCertificateSizeByHandle);
488 NOTREACHED();
489 return nullptr;
490 }
491
202 } // namespace 492 } // namespace
203 493
204 namespace sandbox { 494 namespace sandbox {
205 495
206 // A shared helper test command that will attempt to CreateProcess with a given 496 // A shared helper test command that will attempt to CreateProcess with a given
207 // command line. The second optional parameter will cause the child process to 497 // command line. The second optional parameter will cause the child process to
208 // return that as an exit code on termination. 498 // return that as an exit code on termination.
209 // 499 //
210 // ***Make sure you've enabled basic process creation in the 500 // ***Make sure you've enabled basic process creation in the
211 // test sandbox settings via: 501 // test sandbox settings via:
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), 662 ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"),
373 "GetProcessMitigationPolicy")); 663 "GetProcessMitigationPolicy"));
374 if (!get_process_mitigation_policy) 664 if (!get_process_mitigation_policy)
375 return SBOX_TEST_NOT_FOUND; 665 return SBOX_TEST_NOT_FOUND;
376 666
377 if (!CheckWin8Win32CallPolicy()) 667 if (!CheckWin8Win32CallPolicy())
378 return SBOX_TEST_FIRST_ERROR; 668 return SBOX_TEST_FIRST_ERROR;
379 return SBOX_TEST_SUCCEEDED; 669 return SBOX_TEST_SUCCEEDED;
380 } 670 }
381 671
672 SBOX_TESTS_COMMAND int CheckWin8MonitorsRedirection(int argc, wchar_t** argv) {
673 std::map<HMONITOR, base::string16> monitors = EnumerateMonitors();
674 std::map<HMONITOR, base::string16> monitors_to_test = GetTestMonitors();
675 if (monitors.size() != monitors_to_test.size())
676 return SBOX_TEST_FIRST_ERROR;
677
678 for (const auto& monitor : monitors) {
679 auto result = monitors_to_test.find(monitor.first);
680 if (result == monitors_to_test.end())
681 return SBOX_TEST_SECOND_ERROR;
682 if (result->second != monitor.second)
683 return SBOX_TEST_THIRD_ERROR;
684 }
685 return SBOX_TEST_SUCCEEDED;
686 }
687
688 SBOX_TESTS_COMMAND int CheckWin8MonitorInfo(int argc, wchar_t** argv) {
689 std::map<HMONITOR, base::string16> monitors_to_test = GetTestMonitors();
690 MONITORINFO monitor_info = {};
691 MONITORINFOEXW monitor_info_exw = {};
692 MONITORINFOEXA monitor_info_exa = {};
693 HMONITOR valid_monitor = monitors_to_test.begin()->first;
694 std::wstring valid_device = monitors_to_test.begin()->second;
695 monitor_info.cbSize = sizeof(MONITORINFO);
696 if (!::GetMonitorInfoW(valid_monitor, &monitor_info))
697 return SBOX_TEST_FIRST_ERROR;
698 monitor_info.cbSize = sizeof(MONITORINFO);
699 if (!::GetMonitorInfoA(valid_monitor, &monitor_info))
700 return SBOX_TEST_SECOND_ERROR;
701 monitor_info_exw.cbSize = sizeof(MONITORINFOEXW);
702 if (!::GetMonitorInfoW(valid_monitor,
703 reinterpret_cast<MONITORINFO*>(&monitor_info_exw)) ||
704 valid_device != monitor_info_exw.szDevice) {
705 return SBOX_TEST_THIRD_ERROR;
706 }
707 monitor_info_exa.cbSize = sizeof(MONITORINFOEXA);
708 if (!::GetMonitorInfoA(valid_monitor,
709 reinterpret_cast<MONITORINFO*>(&monitor_info_exa)) ||
710 valid_device != base::ASCIIToUTF16(monitor_info_exa.szDevice)) {
711 return SBOX_TEST_FOURTH_ERROR;
712 }
713
714 // Invalid size checks.
715 monitor_info.cbSize = 0;
716 if (::GetMonitorInfoW(valid_monitor, &monitor_info))
717 return SBOX_TEST_FIFTH_ERROR;
718 monitor_info.cbSize = 0x10000;
719 if (::GetMonitorInfoW(valid_monitor, &monitor_info))
720 return SBOX_TEST_SIXTH_ERROR;
721
722 // Check that an invalid handle isn't accepted.
723 HMONITOR invalid_monitor = reinterpret_cast<HMONITOR>(-1);
724 monitor_info.cbSize = sizeof(MONITORINFO);
725 if (::GetMonitorInfoW(invalid_monitor, &monitor_info))
726 return SBOX_TEST_SEVENTH_ERROR;
727
728 return SBOX_TEST_SUCCEEDED;
729 }
730
731 bool RunTestsOnVideoOutputConfigure(uintptr_t monitor_index,
732 IOPMVideoOutput* video_output) {
733 OPM_CONFIGURE_PARAMETERS config_params = {};
734 OPM_SET_PROTECTION_LEVEL_PARAMETERS* protection_level =
735 reinterpret_cast<OPM_SET_PROTECTION_LEVEL_PARAMETERS*>(
736 config_params.abParameters);
737 protection_level->ulProtectionType = OPM_PROTECTION_TYPE_HDCP;
738 protection_level->ulProtectionLevel = OPM_HDCP_ON;
739 config_params.guidSetting = OPM_SET_PROTECTION_LEVEL;
740 config_params.cbParametersSize = sizeof(OPM_SET_PROTECTION_LEVEL_PARAMETERS);
741 HRESULT hr = video_output->Configure(&config_params, 0, nullptr);
742 if (FAILED(hr))
743 return false;
744 protection_level->ulProtectionType = OPM_PROTECTION_TYPE_DPCP;
745 hr = video_output->Configure(&config_params, 0, nullptr);
746 if (FAILED(hr))
747 return false;
748 protection_level->ulProtectionLevel = OPM_HDCP_OFF;
749 hr = video_output->Configure(&config_params, 0, nullptr);
750 if (FAILED(hr))
751 return false;
752 BYTE dummy_byte = 0;
753 hr = video_output->Configure(&config_params, 1, &dummy_byte);
754 if (SUCCEEDED(hr))
755 return false;
756 protection_level->ulProtectionType = 0xFFFFFFFF;
757 hr = video_output->Configure(&config_params, 0, nullptr);
758 if (SUCCEEDED(hr))
759 return false;
760 // Invalid protection level test.
761 protection_level->ulProtectionType = OPM_PROTECTION_TYPE_HDCP;
762 protection_level->ulProtectionLevel = OPM_HDCP_ON + 1;
763 hr = video_output->Configure(&config_params, 0, nullptr);
764 if (SUCCEEDED(hr))
765 return false;
766 hr = video_output->Configure(&config_params, 0, nullptr);
767 if (SUCCEEDED(hr))
768 return false;
769 config_params.guidSetting = OPM_SET_HDCP_SRM;
770 OPM_SET_HDCP_SRM_PARAMETERS* srm_parameters =
771 reinterpret_cast<OPM_SET_HDCP_SRM_PARAMETERS*>(
772 config_params.abParameters);
773 srm_parameters->ulSRMVersion = 1;
774 config_params.cbParametersSize = sizeof(OPM_SET_HDCP_SRM_PARAMETERS);
775 hr = video_output->Configure(&config_params, 0, nullptr);
776 if (SUCCEEDED(hr))
777 return false;
778 return true;
779 }
780
781 bool RunTestsOnVideoOutputFinishInitialization(uintptr_t monitor_index,
782 IOPMVideoOutput* video_output) {
783 OPM_ENCRYPTED_INITIALIZATION_PARAMETERS init_params = {};
784 memset(init_params.abEncryptedInitializationParameters, 'a' + monitor_index,
785 sizeof(init_params.abEncryptedInitializationParameters));
786 HRESULT hr = video_output->FinishInitialization(&init_params);
787 if (FAILED(hr))
788 return false;
789 memset(init_params.abEncryptedInitializationParameters, 'Z' + monitor_index,
790 sizeof(init_params.abEncryptedInitializationParameters));
791 hr = video_output->FinishInitialization(&init_params);
792 if (SUCCEEDED(hr))
793 return false;
794 return true;
795 }
796
797 bool RunTestsOnVideoOutputStartInitialization(uintptr_t monitor_index,
798 IOPMVideoOutput* video_output) {
799 OPM_RANDOM_NUMBER random_number = {};
800 BYTE* certificate = nullptr;
801 ULONG certificate_length = 0;
802
803 HRESULT hr = video_output->StartInitialization(&random_number, &certificate,
804 &certificate_length);
805 if (FAILED(hr))
806 return false;
807
808 if (certificate_length != CalculateCertLength(monitor_index))
809 return false;
810
811 for (ULONG i = 0; i < certificate_length; ++i) {
812 if (certificate[i] != 'A' + monitor_index)
813 return false;
814 }
815
816 for (ULONG i = 0; i < sizeof(random_number.abRandomNumber); ++i) {
817 if (random_number.abRandomNumber[i] != '!' + monitor_index)
818 return false;
819 }
820
821 return true;
822 }
823
824 static bool SendSingleGetInfoRequest(uintptr_t monitor_index,
825 IOPMVideoOutput* video_output,
826 const GUID& request,
827 ULONG data_length,
828 void* data) {
829 OPM_GET_INFO_PARAMETERS params = {};
830 OPM_REQUESTED_INFORMATION requested_information = {};
831 BYTE* requested_information_ptr =
832 reinterpret_cast<BYTE*>(&requested_information);
833 params.guidInformation = request;
834 params.cbParametersSize = data_length;
835 memcpy(params.abParameters, data, data_length);
836 HRESULT hr = video_output->GetInformation(&params, &requested_information);
837 if (FAILED(hr))
838 return false;
839 for (size_t i = 0; i < sizeof(OPM_REQUESTED_INFORMATION); ++i) {
840 if (requested_information_ptr[i] != '0' + monitor_index)
841 return false;
842 }
843 return true;
844 }
845
846 bool RunTestsOnVideoOutputGetInformation(uintptr_t monitor_index,
847 IOPMVideoOutput* video_output) {
848 ULONG dummy = 0;
849 if (!SendSingleGetInfoRequest(monitor_index, video_output,
850 OPM_GET_CONNECTOR_TYPE, 0, nullptr)) {
851 return false;
852 }
853 if (!SendSingleGetInfoRequest(monitor_index, video_output,
854 OPM_GET_SUPPORTED_PROTECTION_TYPES, 0,
855 nullptr)) {
856 return false;
857 }
858 // These should fail due to invalid parameter sizes.
859 if (SendSingleGetInfoRequest(monitor_index, video_output,
860 OPM_GET_CONNECTOR_TYPE, sizeof(dummy), &dummy)) {
861 return false;
862 }
863 if (SendSingleGetInfoRequest(monitor_index, video_output,
864 OPM_GET_SUPPORTED_PROTECTION_TYPES,
865 sizeof(dummy), &dummy)) {
866 return false;
867 }
868 ULONG protection_type = OPM_PROTECTION_TYPE_HDCP;
869 if (!SendSingleGetInfoRequest(monitor_index, video_output,
870 OPM_GET_ACTUAL_PROTECTION_LEVEL,
871 sizeof(protection_type), &protection_type)) {
872 return false;
873 }
874 protection_type = OPM_PROTECTION_TYPE_DPCP;
875 if (!SendSingleGetInfoRequest(monitor_index, video_output,
876 OPM_GET_ACTUAL_PROTECTION_LEVEL,
877 sizeof(protection_type), &protection_type)) {
878 return false;
879 }
880 // These should fail as unsupported or invalid parameters.
881 protection_type = OPM_PROTECTION_TYPE_ACP;
882 if (SendSingleGetInfoRequest(monitor_index, video_output,
883 OPM_GET_ACTUAL_PROTECTION_LEVEL,
884 sizeof(protection_type), &protection_type)) {
885 return false;
886 }
887 if (SendSingleGetInfoRequest(monitor_index, video_output,
888 OPM_GET_ACTUAL_PROTECTION_LEVEL, 0, nullptr)) {
889 return false;
890 }
891 protection_type = OPM_PROTECTION_TYPE_HDCP;
892 if (!SendSingleGetInfoRequest(monitor_index, video_output,
893 OPM_GET_VIRTUAL_PROTECTION_LEVEL,
894 sizeof(protection_type), &protection_type)) {
895 return false;
896 }
897 protection_type = OPM_PROTECTION_TYPE_DPCP;
898 if (!SendSingleGetInfoRequest(monitor_index, video_output,
899 OPM_GET_VIRTUAL_PROTECTION_LEVEL,
900 sizeof(protection_type), &protection_type)) {
901 return false;
902 }
903 // These should fail as unsupported or invalid parameters.
904 protection_type = OPM_PROTECTION_TYPE_ACP;
905 if (SendSingleGetInfoRequest(monitor_index, video_output,
906 OPM_GET_VIRTUAL_PROTECTION_LEVEL,
907 sizeof(protection_type), &protection_type)) {
908 return false;
909 }
910 if (SendSingleGetInfoRequest(monitor_index, video_output,
911 OPM_GET_VIRTUAL_PROTECTION_LEVEL, 0, nullptr)) {
912 return false;
913 }
914 // This should fail with unsupported request.
915 if (SendSingleGetInfoRequest(monitor_index, video_output, OPM_GET_CODEC_INFO,
916 0, nullptr)) {
917 return false;
918 }
919 return true;
920 }
921
922 int RunTestsOnVideoOutput(uintptr_t monitor_index,
923 IOPMVideoOutput* video_output) {
924 if (!RunTestsOnVideoOutputStartInitialization(monitor_index, video_output))
925 return SBOX_TEST_FIRST_ERROR;
926
927 if (!RunTestsOnVideoOutputFinishInitialization(monitor_index, video_output))
928 return SBOX_TEST_SECOND_ERROR;
929
930 if (!RunTestsOnVideoOutputConfigure(monitor_index, video_output))
931 return SBOX_TEST_THIRD_ERROR;
932
933 if (!RunTestsOnVideoOutputGetInformation(monitor_index, video_output))
934 return SBOX_TEST_FOURTH_ERROR;
935
936 return SBOX_TEST_SUCCEEDED;
937 }
938
939 SBOX_TESTS_COMMAND int CheckWin8OPMApis(int argc, wchar_t** argv) {
940 std::map<HMONITOR, base::string16> monitors = GetTestMonitors();
941 for (const auto& monitor : monitors) {
942 ULONG output_count = 0;
943 IOPMVideoOutput** outputs = nullptr;
944 uintptr_t monitor_index = reinterpret_cast<uintptr_t>(monitor.first) & 0xF;
945 HRESULT hr = OPMGetVideoOutputsFromHMONITOR(
946 monitor.first, OPM_VOS_OPM_SEMANTICS, &output_count, &outputs);
947 if (monitor_index > 4) {
948 // These should fail because the certificate is too large.
949 if (SUCCEEDED(hr))
950 return SBOX_TEST_FIRST_ERROR;
951 continue;
952 }
953 if (FAILED(hr))
954 return SBOX_TEST_SECOND_ERROR;
955 if (output_count != monitor_index - 1)
956 return SBOX_TEST_THIRD_ERROR;
957 for (ULONG output_index = 0; output_index < output_count; ++output_index) {
958 int result = RunTestsOnVideoOutput(monitor_index, outputs[output_index]);
959 outputs[output_index]->Release();
960 if (result != SBOX_TEST_SUCCEEDED)
961 return result;
962 }
963 ::CoTaskMemFree(outputs);
964 }
965 return SBOX_TEST_SUCCEEDED;
966 }
967
382 // This test validates that setting the MITIGATION_WIN32K_DISABLE mitigation on 968 // This test validates that setting the MITIGATION_WIN32K_DISABLE mitigation on
383 // the target process causes the launch to fail in process initialization. 969 // the target process causes the launch to fail in process initialization.
384 // The test process itself links against user32/gdi32. 970 // The test process itself links against user32/gdi32.
385 TEST(ProcessMitigationsTest, CheckWin8Win32KLockDownFailure) { 971 TEST(ProcessMitigationsTest, CheckWin8Win32KLockDownFailure) {
386 if (base::win::GetVersion() < base::win::VERSION_WIN8) 972 if (base::win::GetVersion() < base::win::VERSION_WIN8)
387 return; 973 return;
388 974
389 TestRunner runner; 975 TestRunner runner;
390 sandbox::TargetPolicy* policy = runner.GetPolicy(); 976 sandbox::TargetPolicy* policy = runner.GetPolicy();
391 977
392 EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_WIN32K_DISABLE), 978 EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_WIN32K_DISABLE),
393 SBOX_ALL_OK); 979 SBOX_ALL_OK);
394 EXPECT_NE(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8Lockdown")); 980 EXPECT_NE(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8Lockdown"));
395 } 981 }
396 982
397 // This test validates that setting the MITIGATION_WIN32K_DISABLE mitigation 983 // This test validates that setting the MITIGATION_WIN32K_DISABLE mitigation
398 // along with the policy to fake user32 and gdi32 initialization successfully 984 // along with the policy to fake user32 and gdi32 initialization successfully
399 // launches the target process. 985 // launches the target process.
400 // The test process itself links against user32/gdi32. 986 // The test process itself links against user32/gdi32.
401 TEST(ProcessMitigationsTest, CheckWin8Win32KLockDownSuccess) { 987 TEST(ProcessMitigationsTest, CheckWin8Win32KLockDownSuccess) {
402 if (base::win::GetVersion() < base::win::VERSION_WIN8) 988 if (base::win::GetVersion() < base::win::VERSION_WIN8)
403 return; 989 return;
404 990
405 TestRunner runner; 991 TestRunner runner;
406 sandbox::TargetPolicy* policy = runner.GetPolicy(); 992 sandbox::TargetPolicy* policy = runner.GetPolicy();
993 ProcessMitigationsWin32KLockdownPolicy::SetOverrideForTestCallback(
994 FunctionOverrideForTest);
407 995
408 EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_WIN32K_DISABLE), 996 EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_WIN32K_DISABLE),
409 SBOX_ALL_OK); 997 SBOX_ALL_OK);
410 EXPECT_EQ(policy->AddRule(sandbox::TargetPolicy::SUBSYS_WIN32K_LOCKDOWN, 998 EXPECT_EQ(policy->AddRule(sandbox::TargetPolicy::SUBSYS_WIN32K_LOCKDOWN,
411 sandbox::TargetPolicy::FAKE_USER_GDI_INIT, NULL), 999 sandbox::TargetPolicy::FAKE_USER_GDI_INIT, NULL),
412 sandbox::SBOX_ALL_OK); 1000 sandbox::SBOX_ALL_OK);
413 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8Lockdown")); 1001 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8Lockdown"));
1002 EXPECT_NE(SBOX_TEST_SUCCEEDED,
1003 runner.RunTest(L"CheckWin8MonitorsRedirection"));
1004 EXPECT_NE(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8MonitorInfo"));
1005 EXPECT_NE(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8OPMApis"));
1006 }
1007
1008 // This test validates the even though we're running under win32k lockdown
1009 // we can use the IPC redirection to enumerate the list of monitors.
1010 TEST(ProcessMitigationsTest, CheckWin8Win32KRedirection) {
1011 if (base::win::GetVersion() < base::win::VERSION_WIN8)
1012 return;
1013
1014 TestRunner runner;
1015 sandbox::TargetPolicy* policy = runner.GetPolicy();
1016 ProcessMitigationsWin32KLockdownPolicy::SetOverrideForTestCallback(
1017 FunctionOverrideForTest);
1018
1019 EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_WIN32K_DISABLE),
1020 SBOX_ALL_OK);
1021 EXPECT_EQ(policy->AddRule(sandbox::TargetPolicy::SUBSYS_WIN32K_LOCKDOWN,
1022 sandbox::TargetPolicy::IMPLEMENT_OPM_APIS, NULL),
1023 sandbox::SBOX_ALL_OK);
1024 policy->SetEnableOPMRedirection();
1025 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8Lockdown"));
1026 EXPECT_EQ(SBOX_TEST_SUCCEEDED,
1027 runner.RunTest(L"CheckWin8MonitorsRedirection"));
1028 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8MonitorInfo"));
1029 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8OPMApis"));
414 } 1030 }
415 1031
416 //------------------------------------------------------------------------------ 1032 //------------------------------------------------------------------------------
417 // Disable non-system font loads (MITIGATION_NONSYSTEM_FONT_DISABLE) 1033 // Disable non-system font loads (MITIGATION_NONSYSTEM_FONT_DISABLE)
418 // >= Win10 1034 // >= Win10
419 //------------------------------------------------------------------------------ 1035 //------------------------------------------------------------------------------
420 1036
421 SBOX_TESTS_COMMAND int CheckWin10FontLockDown(int argc, wchar_t** argv) { 1037 SBOX_TESTS_COMMAND int CheckWin10FontLockDown(int argc, wchar_t** argv) {
422 get_process_mitigation_policy = 1038 get_process_mitigation_policy =
423 reinterpret_cast<GetProcessMitigationPolicyFunction>(::GetProcAddress( 1039 reinterpret_cast<GetProcessMitigationPolicyFunction>(::GetProcAddress(
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 cmd = cmd.Append(L"calc.exe"); 1341 cmd = cmd.Append(L"calc.exe");
726 1342
727 std::wstring test_command(base::StringPrintf(L"TestChildProcess %ls 0x%08X", 1343 std::wstring test_command(base::StringPrintf(L"TestChildProcess %ls 0x%08X",
728 cmd.value().c_str(), 1344 cmd.value().c_str(),
729 STATUS_ACCESS_VIOLATION)); 1345 STATUS_ACCESS_VIOLATION));
730 1346
731 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str())); 1347 EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
732 } 1348 }
733 1349
734 } // namespace sandbox 1350 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698