From 86617873531cab2cd3b15026babe9e49198539ee Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Sat, 17 Oct 2015 15:50:25 +0000 Subject: [PATCH] [KMTESTS:OB] - Add ObHandle test that verifies a couple ZwDuplicateObject behaviors svn path=/trunk/; revision=69566 --- rostests/kmtests/CMakeLists.txt | 4 + rostests/kmtests/kmtest_drv/testlist.c | 8 ++ rostests/kmtests/ntos_ob/ObHandle.c | 136 +++++++++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 rostests/kmtests/ntos_ob/ObHandle.c diff --git a/rostests/kmtests/CMakeLists.txt b/rostests/kmtests/CMakeLists.txt index 730f7f32935..74eff3071dc 100644 --- a/rostests/kmtests/CMakeLists.txt +++ b/rostests/kmtests/CMakeLists.txt @@ -35,6 +35,7 @@ list(APPEND KMTEST_DRV_SOURCE npfs/NpfsFileInfo.c npfs/NpfsHelpers.c npfs/NpfsReadWrite.c + npfs/NpfsSecurity.c npfs/NpfsVolumeInfo.c ntos_cm/CmSecurity.c ntos_ex/ExCallback.c @@ -53,6 +54,7 @@ list(APPEND KMTEST_DRV_SOURCE ntos_io/IoCreateFile.c ntos_io/IoDeviceInterface.c ntos_io/IoEvent.c + ntos_io/IoFilesystem.c ntos_io/IoInterrupt.c ntos_io/IoIrp.c ntos_io/IoMdl.c @@ -60,6 +62,7 @@ list(APPEND KMTEST_DRV_SOURCE ntos_ke/KeDevQueue.c ntos_ke/KeDpc.c ntos_ke/KeEvent.c + ntos_ke/KeFloatingPoint.c ntos_ke/KeGuardedMutex.c ntos_ke/KeIrql.c ntos_ke/KeMutex.c @@ -72,6 +75,7 @@ list(APPEND KMTEST_DRV_SOURCE ntos_mm/ZwAllocateVirtualMemory.c ntos_mm/ZwCreateSection.c ntos_mm/ZwMapViewOfSection.c + ntos_ob/ObHandle.c ntos_ob/ObReference.c ntos_ob/ObType.c ntos_ob/ObTypes.c diff --git a/rostests/kmtests/kmtest_drv/testlist.c b/rostests/kmtests/kmtest_drv/testlist.c index 9a471b697b9..e8b58637538 100644 --- a/rostests/kmtests/kmtest_drv/testlist.c +++ b/rostests/kmtests/kmtest_drv/testlist.c @@ -26,6 +26,7 @@ KMT_TESTFUNC Test_FsRtlTunnel; KMT_TESTFUNC Test_IoCreateFile; KMT_TESTFUNC Test_IoDeviceInterface; KMT_TESTFUNC Test_IoEvent; +KMT_TESTFUNC Test_IoFilesystem; KMT_TESTFUNC Test_IoInterrupt; KMT_TESTFUNC Test_IoIrp; KMT_TESTFUNC Test_IoMdl; @@ -33,6 +34,7 @@ KMT_TESTFUNC Test_KeApc; KMT_TESTFUNC Test_KeDeviceQueue; KMT_TESTFUNC Test_KeDpc; KMT_TESTFUNC Test_KeEvent; +KMT_TESTFUNC Test_KeFloatingPoint; KMT_TESTFUNC Test_KeGuardedMutex; KMT_TESTFUNC Test_KeIrql; KMT_TESTFUNC Test_KeMutex; @@ -47,7 +49,9 @@ KMT_TESTFUNC Test_NpfsConnect; KMT_TESTFUNC Test_NpfsCreate; KMT_TESTFUNC Test_NpfsFileInfo; KMT_TESTFUNC Test_NpfsReadWrite; +KMT_TESTFUNC Test_NpfsSecurity; KMT_TESTFUNC Test_NpfsVolumeInfo; +KMT_TESTFUNC Test_ObHandle; KMT_TESTFUNC Test_ObReference; KMT_TESTFUNC Test_ObType; KMT_TESTFUNC Test_ObTypeClean; @@ -89,6 +93,7 @@ const KMT_TEST TestList[] = { "IoCreateFile", Test_IoCreateFile }, { "IoDeviceInterface", Test_IoDeviceInterface }, { "IoEvent", Test_IoEvent }, + { "IoFilesystem", Test_IoFilesystem }, { "IoInterrupt", Test_IoInterrupt }, { "IoIrp", Test_IoIrp }, { "IoMdl", Test_IoMdl }, @@ -96,6 +101,7 @@ const KMT_TEST TestList[] = { "KeDeviceQueue", Test_KeDeviceQueue }, { "KeDpc", Test_KeDpc }, { "KeEvent", Test_KeEvent }, + { "KeFloatingPoint", Test_KeFloatingPoint }, { "KeGuardedMutex", Test_KeGuardedMutex }, { "KeIrql", Test_KeIrql }, { "KeMutex", Test_KeMutex }, @@ -110,7 +116,9 @@ const KMT_TEST TestList[] = { "NpfsCreate", Test_NpfsCreate }, { "NpfsFileInfo", Test_NpfsFileInfo }, { "NpfsReadWrite", Test_NpfsReadWrite }, + { "NpfsSecurity", Test_NpfsSecurity }, { "NpfsVolumeInfo", Test_NpfsVolumeInfo }, + { "ObHandle", Test_ObHandle }, { "ObReference", Test_ObReference }, { "ObType", Test_ObType }, { "-ObTypeClean", Test_ObTypeClean }, diff --git a/rostests/kmtests/ntos_ob/ObHandle.c b/rostests/kmtests/ntos_ob/ObHandle.c new file mode 100644 index 00000000000..a0ad9b1c069 --- /dev/null +++ b/rostests/kmtests/ntos_ob/ObHandle.c @@ -0,0 +1,136 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Kernel-Mode Test Suite Object Handle test + * PROGRAMMER: Thomas Faber + */ + +#include + +#include + +#define CheckObject(Handle, Pointers, Handles, Attrib, Access) do \ +{ \ + PUBLIC_OBJECT_BASIC_INFORMATION ObjectInfo; \ + Status = ZwQueryObject(Handle, ObjectBasicInformation, \ + &ObjectInfo, sizeof ObjectInfo, NULL); \ + ok_eq_hex(Status, STATUS_SUCCESS); \ + ok_eq_hex(ObjectInfo.Attributes, Attrib); \ + ok_eq_hex(ObjectInfo.GrantedAccess, Access); \ + ok_eq_ulong(ObjectInfo.PointerCount, Pointers); \ + ok_eq_ulong(ObjectInfo.HandleCount, Handles); \ +} while (0) + +#define KERNEL_HANDLE_FLAG ((ULONG_PTR)0xFFFFFFFF80000000) +#define IsUserHandle(h) (((ULONG_PTR)(h) & KERNEL_HANDLE_FLAG) == 0) +#define IsKernelHandle(h) (((ULONG_PTR)(h) & KERNEL_HANDLE_FLAG) == KERNEL_HANDLE_FLAG) + +static +VOID +TestDuplicate( + _In_ HANDLE Handle) +{ + NTSTATUS Status; + HANDLE NewHandle; + struct + { + ACCESS_MASK DesiredAccess; + ULONG RequestedAttributes; + ULONG Options; + ACCESS_MASK GrantedAccess; + ULONG ExpectedAttributes; + } Tests[] = + { + { DIRECTORY_ALL_ACCESS, 0, 0, + DIRECTORY_ALL_ACCESS, 0 }, + { DIRECTORY_ALL_ACCESS, OBJ_KERNEL_HANDLE, 0, + DIRECTORY_ALL_ACCESS, 0 }, + { DIRECTORY_QUERY, 0, 0, + DIRECTORY_QUERY, 0 }, + { DIRECTORY_QUERY, OBJ_INHERIT, 0, + DIRECTORY_QUERY, OBJ_INHERIT }, + { DIRECTORY_QUERY, OBJ_INHERIT, DUPLICATE_SAME_ACCESS, + DIRECTORY_ALL_ACCESS, OBJ_INHERIT }, + /* 5 */ + { DIRECTORY_QUERY, OBJ_INHERIT, DUPLICATE_SAME_ATTRIBUTES, + DIRECTORY_QUERY, 0 }, + { DIRECTORY_QUERY, OBJ_INHERIT, DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES, + DIRECTORY_ALL_ACCESS, 0 }, + }; + ULONG i; + + for (i = 0; i < RTL_NUMBER_OF(Tests); i++) + { + trace("Test %lu\n", i); + Status = ZwDuplicateObject(ZwCurrentProcess(), + Handle, + ZwCurrentProcess(), + &NewHandle, + Tests[i].DesiredAccess, + Tests[i].RequestedAttributes, + Tests[i].Options); + ok_eq_hex(Status, STATUS_SUCCESS); + if (!skip(NT_SUCCESS(Status), "DuplicateHandle failed\n")) + { + ok(IsUserHandle(NewHandle), "New handle = %p\n", NewHandle); + CheckObject(NewHandle, 3UL, 2UL, Tests[i].ExpectedAttributes, Tests[i].GrantedAccess); + CheckObject(Handle, 3UL, 2UL, 0UL, DIRECTORY_ALL_ACCESS); + + Status = ObCloseHandle(NewHandle, UserMode); + ok_eq_hex(Status, STATUS_SUCCESS); + CheckObject(Handle, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS); + } + } +} + +START_TEST(ObHandle) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE KernelDirectoryHandle; + HANDLE UserDirectoryHandle; + + InitializeObjectAttributes(&ObjectAttributes, + NULL, + 0, + NULL, + NULL); + Status = ZwCreateDirectoryObject(&UserDirectoryHandle, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + ok_eq_hex(Status, STATUS_SUCCESS); + if (!skip(NT_SUCCESS(Status), "No directory handle\n")) + { + ok(IsUserHandle(UserDirectoryHandle), "User handle = %p\n", UserDirectoryHandle); + CheckObject(UserDirectoryHandle, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS); + + TestDuplicate(UserDirectoryHandle); + + Status = ObCloseHandle(UserDirectoryHandle, UserMode); + ok_eq_hex(Status, STATUS_SUCCESS); + } + + InitializeObjectAttributes(&ObjectAttributes, + NULL, + OBJ_KERNEL_HANDLE, + NULL, + NULL); + Status = ZwCreateDirectoryObject(&KernelDirectoryHandle, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + ok_eq_hex(Status, STATUS_SUCCESS); + if (!skip(NT_SUCCESS(Status), "No directory handle\n")) + { + ok(IsKernelHandle(KernelDirectoryHandle), "Kernel handle = %p\n", KernelDirectoryHandle); + CheckObject(KernelDirectoryHandle, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS); + + TestDuplicate(KernelDirectoryHandle); + + Status = ObCloseHandle(KernelDirectoryHandle, UserMode); + ok_eq_hex(Status, STATUS_INVALID_HANDLE); + CheckObject(KernelDirectoryHandle, 2UL, 1UL, 0UL, DIRECTORY_ALL_ACCESS); + + Status = ObCloseHandle(KernelDirectoryHandle, KernelMode); + ok_eq_hex(Status, STATUS_SUCCESS); + } +}