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

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