[KMTESTS:OB]
authorThomas Faber <thomas.faber@reactos.org>
Mon, 17 Oct 2016 09:28:15 +0000 (09:28 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Mon, 17 Oct 2016 09:28:15 +0000 (09:28 +0000)
- Add a test for the NT directory structure's ACLs
CORE-9184

svn path=/trunk/; revision=72976

rostests/kmtests/CMakeLists.txt
rostests/kmtests/kmtest_drv/testlist.c
rostests/kmtests/ntos_ob/ObSecurity.c [new file with mode: 0644]

index 108358f..4f767fb 100644 (file)
@@ -79,6 +79,7 @@ list(APPEND KMTEST_DRV_SOURCE
     ntos_mm/ZwMapViewOfSection.c
     ntos_ob/ObHandle.c
     ntos_ob/ObReference.c
     ntos_mm/ZwMapViewOfSection.c
     ntos_ob/ObHandle.c
     ntos_ob/ObReference.c
+    ntos_ob/ObSecurity.c
     ntos_ob/ObSymbolicLink.c
     ntos_ob/ObType.c
     ntos_ob/ObTypes.c
     ntos_ob/ObSymbolicLink.c
     ntos_ob/ObType.c
     ntos_ob/ObTypes.c
index 3784b0f..5574e89 100644 (file)
@@ -54,6 +54,7 @@ KMT_TESTFUNC Test_NpfsReadWrite;
 KMT_TESTFUNC Test_NpfsVolumeInfo;
 KMT_TESTFUNC Test_ObHandle;
 KMT_TESTFUNC Test_ObReference;
 KMT_TESTFUNC Test_NpfsVolumeInfo;
 KMT_TESTFUNC Test_ObHandle;
 KMT_TESTFUNC Test_ObReference;
+KMT_TESTFUNC Test_ObSecurity;
 KMT_TESTFUNC Test_ObSymbolicLink;
 KMT_TESTFUNC Test_ObType;
 KMT_TESTFUNC Test_ObTypeClean;
 KMT_TESTFUNC Test_ObSymbolicLink;
 KMT_TESTFUNC Test_ObType;
 KMT_TESTFUNC Test_ObTypeClean;
@@ -124,6 +125,7 @@ const KMT_TEST TestList[] =
     { "NpfsVolumeInfo",                     Test_NpfsVolumeInfo },
     { "ObHandle",                           Test_ObHandle },
     { "ObReference",                        Test_ObReference },
     { "NpfsVolumeInfo",                     Test_NpfsVolumeInfo },
     { "ObHandle",                           Test_ObHandle },
     { "ObReference",                        Test_ObReference },
+    { "ObSecurity",                         Test_ObSecurity },
     { "ObSymbolicLink",                     Test_ObSymbolicLink },
     { "ObType",                             Test_ObType },
     { "-ObTypeClean",                       Test_ObTypeClean },
     { "ObSymbolicLink",                     Test_ObSymbolicLink },
     { "ObType",                             Test_ObType },
     { "-ObTypeClean",                       Test_ObTypeClean },
diff --git a/rostests/kmtests/ntos_ob/ObSecurity.c b/rostests/kmtests/ntos_ob/ObSecurity.c
new file mode 100644 (file)
index 0000000..4ac9478
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * PROJECT:         ReactOS kernel-mode tests
+ * LICENSE:         LGPLv2.1+ - See COPYING.LIB in the top level directory
+ * PURPOSE:         Kernel-Mode Test Suite object security test
+ * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
+ */
+
+#include <kmt_test.h>
+#include "../ntos_se/se.h"
+
+#define CheckDirectorySecurityWithOwnerAndGroup(name, Owner, Group, AceCount, ...) CheckDirectorySecurity_(name, Owner, Group, AceCount, __FILE__, __LINE__, ##__VA_ARGS__)
+#define CheckDirectorySecurity(name, AceCount, ...) CheckDirectorySecurity_(name, SeExports->SeAliasAdminsSid, SeExports->SeLocalSystemSid, AceCount, __FILE__, __LINE__, ##__VA_ARGS__)
+#define CheckDirectorySecurity_(name, Owner, Group, AceCount, file, line, ...) CheckDirectorySecurity__(name, Owner, Group, AceCount, file ":" KMT_STRINGIZE(line), ##__VA_ARGS__)
+static
+VOID
+CheckDirectorySecurity__(
+    _In_ PCWSTR DirectoryName,
+    _In_ PSID ExpectedOwner,
+    _In_ PSID ExpectedGroup,
+    _In_ ULONG AceCount,
+    _In_ PCSTR FileAndLine,
+    ...)
+{
+    NTSTATUS Status;
+    UNICODE_STRING DirectoryNameString;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    HANDLE DirectoryHandle;
+    PSECURITY_DESCRIPTOR SecurityDescriptor;
+    ULONG SecurityDescriptorSize;
+    PSID Owner;
+    PSID Group;
+    PACL Dacl;
+    PACL Sacl;
+    BOOLEAN Present;
+    BOOLEAN Defaulted;
+    va_list Arguments;
+
+    RtlInitUnicodeString(&DirectoryNameString, DirectoryName);
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &DirectoryNameString,
+                               OBJ_KERNEL_HANDLE,
+                               NULL,
+                               NULL);
+    Status = ZwOpenDirectoryObject(&DirectoryHandle,
+                                   READ_CONTROL | ACCESS_SYSTEM_SECURITY,
+                                   &ObjectAttributes);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+    if (skip(NT_SUCCESS(Status), "No directory (%ls)\n", DirectoryName))
+    {
+        return;
+    }
+
+    Status = ZwQuerySecurityObject(DirectoryHandle,
+                                   OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
+                                   NULL,
+                                   0,
+                                   &SecurityDescriptorSize);
+    ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL);
+    if (skip(Status == STATUS_BUFFER_TOO_SMALL, "No security size (%ls)\n", DirectoryName))
+    {
+        ObCloseHandle(DirectoryHandle, KernelMode);
+        return;
+    }
+
+    SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
+                                               SecurityDescriptorSize,
+                                               'dSmK');
+    ok(SecurityDescriptor != NULL, "Failed to allocate %lu bytes\n", SecurityDescriptorSize);
+    if (skip(SecurityDescriptor != NULL, "No memory for descriptor (%ls)\n", DirectoryName))
+    {
+        ObCloseHandle(DirectoryHandle, KernelMode);
+        return;
+    }
+
+    Status = ZwQuerySecurityObject(DirectoryHandle,
+                                   OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
+                                   SecurityDescriptor,
+                                   SecurityDescriptorSize,
+                                   &SecurityDescriptorSize);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+    if (NT_SUCCESS(Status))
+    {
+        Owner = NULL;
+        Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor,
+                                               &Owner,
+                                               &Defaulted);
+        if (ExpectedOwner)
+            CheckSid__(Owner, NO_SIZE, ExpectedOwner, FileAndLine);
+        ok(Defaulted == FALSE, "Owner defaulted for %ls\n", DirectoryName);
+
+        Group = NULL;
+        Status = RtlGetGroupSecurityDescriptor(SecurityDescriptor,
+                                               &Group,
+                                               &Defaulted);
+        if (ExpectedGroup)
+            CheckSid__(Group, NO_SIZE, ExpectedGroup, FileAndLine);
+        ok(Defaulted == FALSE, "Group defaulted for %ls\n", DirectoryName);
+
+        Dacl = NULL;
+        Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
+                                              &Present,
+                                              &Dacl,
+                                              &Defaulted);
+        ok_eq_hex(Status, STATUS_SUCCESS);
+        ok(Present == TRUE, "DACL not present for %ls\n", DirectoryName);
+        ok(Defaulted == FALSE, "DACL defaulted for %ls\n", DirectoryName);
+        va_start(Arguments, FileAndLine);
+        VCheckAcl__(Dacl, AceCount, FileAndLine, Arguments);
+        va_end(Arguments);
+
+        Sacl = NULL;
+        Status = RtlGetSaclSecurityDescriptor(SecurityDescriptor,
+                                              &Present,
+                                              &Sacl,
+                                              &Defaulted);
+        ok_eq_hex(Status, STATUS_SUCCESS);
+        ok(Present == FALSE, "SACL present for %ls\n", DirectoryName);
+        ok(Defaulted == FALSE, "SACL defaulted for %ls\n", DirectoryName);
+        ok(Sacl == NULL, "Sacl is %p for %ls\n", Sacl, DirectoryName);
+    }
+    ExFreePoolWithTag(SecurityDescriptor, 'dSmK');
+    ObCloseHandle(DirectoryHandle, KernelMode);
+}
+
+START_TEST(ObSecurity)
+{
+#define DIRECTORY_GENERIC_READ      STANDARD_RIGHTS_READ | DIRECTORY_TRAVERSE | DIRECTORY_QUERY
+#define DIRECTORY_GENERIC_WRITE     STANDARD_RIGHTS_WRITE | DIRECTORY_CREATE_SUBDIRECTORY | DIRECTORY_CREATE_OBJECT
+
+    CheckDirectorySecurityWithOwnerAndGroup(L"\\??", SeExports->SeAliasAdminsSid, NULL, // Group is "Domain Users"
+                           4, ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE |
+                                                       OBJECT_INHERIT_ACE,      SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
+                              ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE |
+                                                       OBJECT_INHERIT_ACE,      SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS,
+                              ACCESS_ALLOWED_ACE_TYPE, 0,                       SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS,
+                              ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
+                                                       CONTAINER_INHERIT_ACE |
+                                                       OBJECT_INHERIT_ACE,      SeExports->SeCreatorOwnerSid,GENERIC_ALL);
+
+    CheckDirectorySecurity(L"\\",
+                           4, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid,       DIRECTORY_GENERIC_READ,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeRestrictedSid,  DIRECTORY_GENERIC_READ);
+
+    CheckDirectorySecurity(L"\\ArcName",
+                           4, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid,       DIRECTORY_GENERIC_READ,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeRestrictedSid,  DIRECTORY_GENERIC_READ);
+
+    CheckDirectorySecurity(L"\\BaseNamedObjects",
+                           3, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid,       DIRECTORY_GENERIC_WRITE | DIRECTORY_GENERIC_READ,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeRestrictedSid,  DIRECTORY_TRAVERSE);
+
+    CheckDirectorySecurity(L"\\Callback",
+                           3, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid,       DIRECTORY_GENERIC_READ,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS);
+
+    CheckDirectorySecurity(L"\\Device",
+                           4, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid,       DIRECTORY_GENERIC_READ,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeRestrictedSid,  DIRECTORY_GENERIC_READ);
+
+    CheckDirectorySecurity(L"\\Driver",
+                           2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_GENERIC_READ);
+
+    CheckDirectorySecurity(L"\\GLOBAL??",
+                           6, ACCESS_ALLOWED_ACE_TYPE, 0,                       SeExports->SeWorldSid,       DIRECTORY_GENERIC_READ,
+                              ACCESS_ALLOWED_ACE_TYPE, 0,                       SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
+                              ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
+                                                       CONTAINER_INHERIT_ACE |
+                                                       OBJECT_INHERIT_ACE,      SeExports->SeWorldSid,       GENERIC_EXECUTE,
+                              ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
+                                                       CONTAINER_INHERIT_ACE |
+                                                       OBJECT_INHERIT_ACE,      SeExports->SeAliasAdminsSid, GENERIC_ALL,
+                              ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
+                                                       CONTAINER_INHERIT_ACE |
+                                                       OBJECT_INHERIT_ACE,      SeExports->SeLocalSystemSid, GENERIC_ALL,
+                              ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE |
+                                                       CONTAINER_INHERIT_ACE |
+                                                       OBJECT_INHERIT_ACE,      SeExports->SeCreatorOwnerSid,GENERIC_ALL);
+
+    CheckDirectorySecurity(L"\\KernelObjects",
+                           3, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid,       DIRECTORY_GENERIC_READ,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS);
+
+    CheckDirectorySecurity(L"\\ObjectTypes",
+                           2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS,
+                              ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_GENERIC_READ);
+}