Author: fireball
Date: Wed Jun 5 23:16:14 2013
New Revision: 59178
URL:
http://svn.reactos.org/svn/reactos?rev=59178&view=rev
Log:
[KMTEST]
- Add tests for SeQueryInformationToken NTAPI. By Moscow State Technical University
students Constantine Belev, Denis Grishin, Egor Sinitsyn.
- Disabled from testbot because they bugcheck ReactOS (unimplemented functions bugcheck).
Work in progress...
Added:
trunk/rostests/kmtests/ntos_se/ (with props)
trunk/rostests/kmtests/ntos_se/SeQueryInfoToken.c (with props)
Modified:
trunk/rostests/kmtests/CMakeLists.txt
trunk/rostests/kmtests/kmtest_drv/testlist.c
Modified: trunk/rostests/kmtests/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/CMakeLists.txt?re…
==============================================================================
--- trunk/rostests/kmtests/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rostests/kmtests/CMakeLists.txt [iso-8859-1] Wed Jun 5 23:16:14 2013
@@ -60,6 +60,7 @@
ntos_ob/ObType.c
ntos_ob/ObTypes.c
ntos_ps/PsNotify.c
+ ntos_se/SeQueryInfoToken.c
${COMMON_SOURCE}
kmtest_drv/kmtest_drv.rc)
Modified: trunk/rostests/kmtests/kmtest_drv/testlist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/kmtest_drv/testli…
==============================================================================
--- trunk/rostests/kmtests/kmtest_drv/testlist.c [iso-8859-1] (original)
+++ trunk/rostests/kmtests/kmtest_drv/testlist.c [iso-8859-1] Wed Jun 5 23:16:14 2013
@@ -43,6 +43,7 @@
KMT_TESTFUNC Test_ObTypeNoClean;
KMT_TESTFUNC Test_ObTypes;
KMT_TESTFUNC Test_PsNotify;
+KMT_TESTFUNC Test_SeQueryInfoToken;
KMT_TESTFUNC Test_RtlAvlTree;
KMT_TESTFUNC Test_RtlException;
KMT_TESTFUNC Test_RtlMemory;
@@ -90,6 +91,7 @@
{ "-ObTypeNoClean", Test_ObTypeNoClean },
{ "ObTypes", Test_ObTypes },
{ "PsNotify", Test_PsNotify },
+ { "-SeQueryInfoToken", Test_SeQueryInfoToken },
{ "RtlAvlTreeKM", Test_RtlAvlTree },
{ "RtlExceptionKM", Test_RtlException },
{ "RtlMemoryKM", Test_RtlMemory },
Propchange: trunk/rostests/kmtests/ntos_se/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Wed Jun 5 23:16:14 2013
@@ -0,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)
Propchange: trunk/rostests/kmtests/ntos_se/
------------------------------------------------------------------------------
bugtraq:message = See issue #%BUGID% for more details.
Propchange: trunk/rostests/kmtests/ntos_se/
------------------------------------------------------------------------------
bugtraq:url =
http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Propchange: trunk/rostests/kmtests/ntos_se/
------------------------------------------------------------------------------
tsvn:logminsize = 10
Added: trunk/rostests/kmtests/ntos_se/SeQueryInfoToken.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_se/SeQueryIn…
==============================================================================
--- trunk/rostests/kmtests/ntos_se/SeQueryInfoToken.c (added)
+++ trunk/rostests/kmtests/ntos_se/SeQueryInfoToken.c [iso-8859-1] Wed Jun 5 23:16:14
2013
@@ -0,0 +1,342 @@
+/*
+* PROJECT: ReactOS kernel-mode tests
+* LICENSE: GPLv2+ - See COPYING in the top level directory
+* PURPOSE: Kernel-Mode Test Suite Process Notification Routines test
+* PROGRAMMER: Constantine Belev (Moscow State Technical University)
+* Denis Grishin (Moscow State Technical University)
+* Egor Sinitsyn (Moscow State Technical University)
+*/
+
+#include <kmt_test.h>
+#include <ntifs.h>
+
+#define NDEBUG
+#include <debug.h>
+
+//------------------------------------------------------------------------------//
+// Functions required forWorking with ACCESS_STATE structure //
+//------------------------------------------------------------------------------//
+
+NTKERNELAPI NTSTATUS NTAPI SeCreateAccessState(
+ PACCESS_STATE AccessState,
+ PVOID AuxData,
+ ACCESS_MASK DesiredAccess,
+ PGENERIC_MAPPING Mapping
+ );
+
+NTKERNELAPI VOID NTAPI SeDeleteAccessState(
+ PACCESS_STATE AccessState
+ );
+
+//------------------------------------------------------------------------------//
+// Testing Functions //
+//------------------------------------------------------------------------------//
+
+// Testing function for SQIT
+
+void TestsSeQueryInformationToken(PACCESS_TOKEN Token)
+{
+ NTSTATUS Status;
+ PVOID Buffer = NULL;
+ PSID sid;
+ PTOKEN_OWNER Towner;
+ PTOKEN_DEFAULT_DACL TDefDacl;
+ PTOKEN_GROUPS TGroups;
+ ULONG GroupCount;
+ PACL acl;
+ PTOKEN_STATISTICS TStats;
+ PTOKEN_TYPE TType;
+ PTOKEN_USER TUser;
+ //NTSTATUS ExceptionStatus;
+
+ //----------------------------------------------------------------//
+ // Testing SeQueryInformationToken with various args //
+ //----------------------------------------------------------------//
+
+ ok(Token != NULL, "Token is not captured. Testing SQIT interrupted\n\n");
+
+ if (Token == NULL) return;
+
+ Status = SeQueryInformationToken(Token, TokenOwner, &Buffer);
+ ok((Status == STATUS_SUCCESS), "SQIT with TokenOwner arg fails with \n");
+ if (Buffer)
+ {
+ Towner = (TOKEN_OWNER *)Buffer;
+ sid = Towner->Owner;
+ ok((RtlValidSid(sid) == TRUE), "TokenOwner's SID is not a valid
SID\n");
+ ExFreePool(Buffer);
+ }
+
+ ok((SeQueryInformationToken(Token, TokenDefaultDacl, &Buffer) == STATUS_SUCCESS),
"SQIT with TokenDefaultDacl fails\n");
+ if (Buffer) {
+ TDefDacl = (PTOKEN_DEFAULT_DACL)Buffer;
+ acl = TDefDacl->DefaultDacl;
+ ok(((acl->AclRevision == ACL_REVISION || acl->AclRevision ==
ACL_REVISION_DS) == TRUE), "DACL is invalid\n");
+ ExFreePool(Buffer);
+ }
+
+ ok((SeQueryInformationToken(Token, TokenGroups, &Buffer) == STATUS_SUCCESS),
"SQIT with TokenGroups fails\n");
+ if (Buffer)
+ {
+ TGroups = (PTOKEN_GROUPS)Buffer;
+ GroupCount = TGroups->GroupCount;
+ int flag = 1;
+ int i;
+ for (i = 0; i < GroupCount; i++)
+ {
+ sid = TGroups->Groups[i].Sid;
+ if (!RtlValidSid(sid))
+ {
+ flag = 0;
+ break;
+ }
+ }
+ ok((flag == TRUE), "TokenGroup's SIDs are not valid\n");
+ ExFreePool(Buffer);
+ }
+
+ //----------------------------------------------------------------//
+
+ ok(SeQueryInformationToken(Token, TokenImpersonationLevel, &Buffer), "SQIT
with TokenImpersonation fails\n");
+
+ //----------------------------------------------------------------//
+
+ // Call SQIT with TokenStatistics
+
+ ok((SeQueryInformationToken(Token, TokenStatistics, &Buffer) == STATUS_SUCCESS),
"SQIT with TokenStatistics fails\n");
+ if (Buffer)
+ {
+ TStats = (PTOKEN_STATISTICS)Buffer;
+ // just put 0 into 1st arg or use trace to print TokenStatistics
+ ok(1, "print statistics:\nTokenID = %u_%d\nSecurityImperLevel =
%d\nPrivCount = %d\nGroupCount = %d\n\n", TStats->TokenId.LowPart,
+ TStats->TokenId.HighPart,
+ TStats->ImpersonationLevel,
+ TStats->PrivilegeCount,
+ TStats->GroupCount
+ );
+ ExFreePool(TStats);
+ }
+
+ //----------------------------------------------------------------//
+
+ // Call SQIT with TokenType
+
+ ok((SeQueryInformationToken(Token, TokenType, &Buffer) == STATUS_SUCCESS),
"SQIT with TokenType fails\n");
+ if (Buffer)
+ {
+ TType = (PTOKEN_TYPE)Buffer;
+ ok((*TType == TokenPrimary || *TType == TokenImpersonation), "TokenType in
not a primary nor impersonation. FAILED\n");
+ ExFreePool(TType);
+ }
+
+ //----------------------------------------------------------------//
+
+ // Call SQIT with TokenUser
+
+ ok((SeQueryInformationToken(Token, TokenUser, &Buffer) == STATUS_SUCCESS),
"SQIT with TokenUser fails\n");
+ if (Buffer)
+ {
+ TUser = (PTOKEN_USER)Buffer;
+ ok(RtlValidSid(TUser->User.Sid), "TokenUser has an invalid Sid\n");
+ ExFreePool(TUser);
+ }
+
+ //----------------------------------------------------------------//
+
+
+ Status = SeQueryInformationToken(Token, TokenSandBoxInert, &Buffer);
+ ok(Status != STATUS_SUCCESS, "SQIT must fail with wrong TOKEN_INFORMATION_CLASS
arg\n");
+}
+
+//------------------------------------------------------------------------------//
+
+//------------------------------------------------------------------------------//
+// Body of the main test //
+//------------------------------------------------------------------------------//
+
+START_TEST(SeQueryInfoToken)
+{
+ PACCESS_STATE AccessState;
+ ACCESS_MASK AccessMask = MAXIMUM_ALLOWED;
+ ACCESS_MASK DesiredAccess = MAXIMUM_ALLOWED;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PAUX_ACCESS_DATA AuxData = NULL;
+ PPRIVILEGE_SET NewPrivilegeSet;
+ BOOLEAN Checker;
+ PPRIVILEGE_SET Privileges = NULL;
+ PSECURITY_SUBJECT_CONTEXT SubjectContext = NULL;
+ PACCESS_TOKEN Token = NULL;
+ PTOKEN_PRIVILEGES TPrivileges;
+ PVOID Buffer;
+ POBJECT_TYPE PsProcessType = NULL;
+ PGENERIC_MAPPING GenericMapping;
+
+ SubjectContext = ExAllocatePool(PagedPool, sizeof(SECURITY_SUBJECT_CONTEXT));
+
+ SeCaptureSubjectContext(SubjectContext);
+ SeLockSubjectContext(SubjectContext);
+ Token = SeQuerySubjectContextToken(SubjectContext);
+
+ // Testing SQIT with current Token
+ TestsSeQueryInformationToken(Token);
+
+ //----------------------------------------------------------------//
+ // Creating an ACCESS_STATE structure //
+ //----------------------------------------------------------------//
+
+ AccessState = ExAllocatePool(PagedPool, sizeof(ACCESS_STATE));
+ PsProcessType = ExAllocatePool(PagedPool, sizeof(OBJECT_TYPE));
+ AuxData = ExAllocatePool(PagedPool, 0xC8);
+ GenericMapping = ExAllocatePool(PagedPool, sizeof(GENERIC_MAPPING));
+
+ Status = SeCreateAccessState(AccessState,
+ (PVOID)AuxData,
+ DesiredAccess,
+ GenericMapping
+ );
+
+ ok((Status == STATUS_SUCCESS), "SeCreateAccessState failed with Status
0x%08X\n", Status);
+
+ SeCaptureSubjectContext(&AccessState->SubjectSecurityContext);
+ SeLockSubjectContext(&AccessState->SubjectSecurityContext);
+
+ Token = SeQuerySubjectContextToken(&AccessState->SubjectSecurityContext);
+
+ // Testing SQIT whti AccessState Token
+ TestsSeQueryInformationToken(Token);
+
+ //----------------------------------------------------------------//
+ // Testing other functions //
+ //----------------------------------------------------------------//
+
+ //----------------------------------------------------------------//
+ // Testing SeAppendPrivileges //
+ //----------------------------------------------------------------//
+
+ AuxData->PrivilegeSet->PrivilegeCount = 1;
+
+ // Testing SeAppendPrivileges. Must change PrivilegeCount to 2 (1 + 1)
+
+ NewPrivilegeSet = ExAllocatePool(PagedPool, sizeof(PRIVILEGE_SET));
+ NewPrivilegeSet->PrivilegeCount = 1;
+
+ ok((SeAppendPrivileges(AccessState, NewPrivilegeSet)) == STATUS_SUCCESS,
"SeAppendPrivileges failed\n");
+ ok((AuxData->PrivilegeSet->PrivilegeCount == 2),"PrivelegeCount must be 2,
but it is %d\n", AuxData->PrivilegeSet->PrivilegeCount);
+ ExFreePool(NewPrivilegeSet);
+
+ //----------------------------------------------------------------//
+
+ // Testing SeAppendPrivileges. Must change PrivilegeCount to 6 (2 + 4)
+
+ NewPrivilegeSet = ExAllocatePool(PagedPool, 4*sizeof(PRIVILEGE_SET));
+ NewPrivilegeSet->PrivilegeCount = 4;
+
+ ok((SeAppendPrivileges(AccessState, NewPrivilegeSet)) == STATUS_SUCCESS,
"SeAppendPrivileges failed\n");
+ ok((AuxData->PrivilegeSet->PrivilegeCount == 6),"PrivelegeCount must be 6,
but it is %d\n", AuxData->PrivilegeSet->PrivilegeCount);
+ ExFreePool(NewPrivilegeSet);
+
+ //----------------------------------------------------------------//
+ // Testing SePrivilegeCheck //
+ //----------------------------------------------------------------//
+
+ // KPROCESSOR_MODE is set to KernelMode ===> Always return TRUE
+ ok(SePrivilegeCheck(AuxData->PrivilegeSet,
&(AccessState->SubjectSecurityContext), KernelMode), "SePrivilegeCheck failed
with KernelMode mode arg\n");
+ // and call it again
+ ok(SePrivilegeCheck(AuxData->PrivilegeSet,
&(AccessState->SubjectSecurityContext), KernelMode), "SePrivilegeCheck failed
with KernelMode mode arg\n");
+
+ //----------------------------------------------------------------//
+
+ // KPROCESSOR_MODE is set to UserMode. Expect false
+ ok(!SePrivilegeCheck(AuxData->PrivilegeSet,
&(AccessState->SubjectSecurityContext), UserMode), "SePrivilegeCheck
unexpected success with UserMode arg\n");
+
+ //----------------------------------------------------------------//
+
+ //----------------------------------------------------------------//
+ // Testing SeFreePrivileges //
+ //----------------------------------------------------------------//
+
+ Privileges = ExAllocatePool(PagedPool,
AuxData->PrivilegeSet->PrivilegeCount*sizeof(PRIVILEGE_SET));
+
+ Checker = SeAccessCheck(
+ AccessState->SecurityDescriptor,
+ &AccessState->SubjectSecurityContext,
+ FALSE,
+ AccessState->OriginalDesiredAccess,
+ AccessState->PreviouslyGrantedAccess,
+ &Privileges,
+ (PGENERIC_MAPPING)((PCHAR*)PsProcessType + 52),
+ KernelMode,
+ &AccessMask,
+ &Status
+ );
+ ok(Checker, "Checker is NULL\n");
+ ok((Privileges != NULL), "Privileges is NULL\n");
+ if (Privileges) SeFreePrivileges(Privileges);
+
+
+ //----------------------------------------------------------------//
+ // Testing SePrivilegeCheck //
+ //----------------------------------------------------------------//
+ // I'm trying to make success call of SePrivilegeCheck from UserMode
+ // If we sets Privileges properly, can we expect true from SePrivilegeCheck?
+ // answer: yes
+ // This test demonstrates it
+
+ SeQueryInformationToken(Token, TokenPrivileges, &Buffer);
+ if (Buffer)
+ {
+ TPrivileges = (PTOKEN_PRIVILEGES)(Buffer);
+ //trace("TPCount = %u\n\n", TPrivileges->PrivilegeCount);
+
+ NewPrivilegeSet = ExAllocatePool(PagedPool, 14*sizeof(PRIVILEGE_SET));
+ NewPrivilegeSet->PrivilegeCount = 14;
+
+ ok((SeAppendPrivileges(AccessState, NewPrivilegeSet)) == STATUS_SUCCESS,
"SeAppendPrivileges failed\n");
+ ok((AuxData->PrivilegeSet->PrivilegeCount == 20),"PrivelegeCount must
be 20, but it is %d\n", AuxData->PrivilegeSet->PrivilegeCount);
+ ExFreePool(NewPrivilegeSet);
+ int i;
+ for (i = 0; i < AuxData->PrivilegeSet->PrivilegeCount; i++)
+ {
+ AuxData->PrivilegeSet->Privilege[i].Attributes =
TPrivileges->Privileges[i].Attributes;
+ AuxData->PrivilegeSet->Privilege[i].Luid =
TPrivileges->Privileges[i].Luid;
+ }
+ //trace("AccessState->privCount = %u\n\n",
((PAUX_ACCESS_DATA)(AccessState->AuxData))->PrivilegeSet->PrivilegeCount);
+
+ ok(SePrivilegeCheck(AuxData->PrivilegeSet,
&(AccessState->SubjectSecurityContext), UserMode), "SePrivilegeCheck fails in
UserMode, but I wish it will success\n");
+ }
+
+ // Call SeFreePrivileges again
+
+ Privileges = ExAllocatePool(PagedPool, 20*sizeof(PRIVILEGE_SET));
+
+ Checker = SeAccessCheck(
+ AccessState->SecurityDescriptor,
+ &AccessState->SubjectSecurityContext,
+ TRUE,
+ AccessState->OriginalDesiredAccess,
+ AccessState->PreviouslyGrantedAccess,
+ &Privileges,
+ (PGENERIC_MAPPING)((PCHAR*)PsProcessType + 52),
+ KernelMode,
+ &AccessMask,
+ &Status
+ );
+ ok(Checker, "Checker is NULL\n");
+ ok((Privileges != NULL), "Privileges is NULL\n");
+ if (Privileges) SeFreePrivileges(Privileges);
+
+ //----------------------------------------------------------------//
+ // Missing for now //
+ //----------------------------------------------------------------//
+
+ SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
+ SeUnlockSubjectContext(SubjectContext);
+
+ SeDeleteAccessState(AccessState);
+
+ if (GenericMapping) ExFreePool(GenericMapping);
+ if (PsProcessType) ExFreePool(PsProcessType);
+ if (SubjectContext) ExFreePool(SubjectContext);
+ if (AuxData) ExFreePool(AuxData);
+ if (AccessState) ExFreePool(AccessState);
+}
Propchange: trunk/rostests/kmtests/ntos_se/SeQueryInfoToken.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: trunk/rostests/kmtests/ntos_se/SeQueryInfoToken.c
------------------------------------------------------------------------------
svn:mime-type = text/plain