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?rev... ============================================================================== --- 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/testlis... ============================================================================== --- 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/SeQueryInf... ============================================================================== --- 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