mirror of
https://github.com/reactos/reactos.git
synced 2025-02-28 19:32:59 +00:00
[0.4.15][NTOS:SE][NDK][KMTESTS:SE] Fix 'kmtest_.exe SeQueryInfoToken' (#5308)
This backport fixes 'kmtest_.exe SeQueryInfoToken' on all testers: VBox x86, KVM x86, WHS x86, Win2003_x64. And according to Thomas description may also prevent a buffer overrun when executing that formerly broken test. Afterwards all 76 tests of this suite do complete on all those builders. Before the patch only 74 of those tests succeeded, 2 failed. The fix is a squashed backport of the following 6 commits from Thomas Faber: 0.4.16-dev-11-g44bdafa17e
[KMTESTS:SE] Fix failing tests (#5308) 0.4.16-dev-10-gbf6af0f52e
[NTOS:SE] Mark output parameters as such (#5308) 0.4.16-dev-9-g156053cafd
[NDK] Match AUX_ACCESS_DATA definition with publicly available version. - if you allocated only sizeof(AUX_ACCESS_DATA), the test would crash with a 4 byte buffer overflow. (#5308) 0.4.16-dev-8-gff410211e9
[KMTESTS:SE] Don't modify internal data structure, this might cause buffer overrun (#5308) 0.4.16-dev-7-g206df96bc4
[KMTESTS:SE] Correctly allocate PrivilegeSet buffers (#5308) 0.4.16-dev-6-g64a6bd4c3e
[KMTESTS:SE] Avoid use of uninitialized pool and hardcoded offsets (#5308) WHS x86 before-and-after-state, the after-test had a few fixes from Timos unrelated PR7343 inside unfortunately: https://reactos.org/testman/compare.php?ids=97640,97871 (This is added to prove the test being wrong) I tested it also successfully on my local 2k3sp2 x86 with the releases/0.4.15 afterstate, built with RosBEWin2.2.2 GCC8.4.0dbg x86. Win2003_x64 0.4.16-dev-11-g44bdafa at 2024-09-12 15:19 (after-state): https://reactos.org/testman/compare.php?ids=97791 0.4.16-dev-5-g2913ef5 vs. 0.4.16-dev-11-g44bdafa vs. 0.4.16-dev-23-g53b304e: VBox x86 https://reactos.org/testman/compare.php?ids=97795,97806,97877 0.4.16-dev-5-g2913ef5 vs. 0.4.16-dev-20-g144a8b5 vs. 0.4.16-dev-21-g2af6fd4: KVM x86 https://reactos.org/testman/compare.php?ids=97793,97855,97856 Since we do touch the NTOS and NDK here the fix is not guaranteed to be side-effect-free, but since we are so early in the RC-phase, I dared to pick it, especially since the alternative would have been to disable the test altogether in the releases/0.4.15 which would have been a pity, if we can also have it all green everywhere.
This commit is contained in:
parent
5f1fcb59e5
commit
3780e42ff9
5 changed files with 96 additions and 58 deletions
|
@ -13,6 +13,19 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
// Copied from PspProcessMapping -- although the values don't matter much for
|
||||||
|
// the most part.
|
||||||
|
static GENERIC_MAPPING ProcessGenericMapping =
|
||||||
|
{
|
||||||
|
STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
|
||||||
|
STANDARD_RIGHTS_WRITE | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD |
|
||||||
|
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE |
|
||||||
|
PROCESS_TERMINATE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION |
|
||||||
|
PROCESS_SUSPEND_RESUME,
|
||||||
|
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
|
||||||
|
PROCESS_ALL_ACCESS
|
||||||
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------//
|
//------------------------------------------------------------------------------//
|
||||||
// Testing Functions //
|
// Testing Functions //
|
||||||
//------------------------------------------------------------------------------//
|
//------------------------------------------------------------------------------//
|
||||||
|
@ -216,14 +229,13 @@ START_TEST(SeQueryInfoToken)
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PAUX_ACCESS_DATA AuxData = NULL;
|
PAUX_ACCESS_DATA AuxData = NULL;
|
||||||
PPRIVILEGE_SET NewPrivilegeSet;
|
PPRIVILEGE_SET NewPrivilegeSet;
|
||||||
|
ULONG InitialPrivilegeCount;
|
||||||
BOOLEAN Checker;
|
BOOLEAN Checker;
|
||||||
PPRIVILEGE_SET Privileges = NULL;
|
PPRIVILEGE_SET Privileges = NULL;
|
||||||
PSECURITY_SUBJECT_CONTEXT SubjectContext = NULL;
|
PSECURITY_SUBJECT_CONTEXT SubjectContext = NULL;
|
||||||
PACCESS_TOKEN Token = NULL;
|
PACCESS_TOKEN Token = NULL;
|
||||||
PTOKEN_PRIVILEGES TPrivileges;
|
PTOKEN_PRIVILEGES TPrivileges;
|
||||||
PVOID Buffer;
|
PVOID Buffer;
|
||||||
POBJECT_TYPE PsProcessType = NULL;
|
|
||||||
PGENERIC_MAPPING GenericMapping;
|
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
SubjectContext = ExAllocatePool(PagedPool, sizeof(SECURITY_SUBJECT_CONTEXT));
|
SubjectContext = ExAllocatePool(PagedPool, sizeof(SECURITY_SUBJECT_CONTEXT));
|
||||||
|
@ -240,14 +252,14 @@ START_TEST(SeQueryInfoToken)
|
||||||
//----------------------------------------------------------------//
|
//----------------------------------------------------------------//
|
||||||
|
|
||||||
AccessState = ExAllocatePool(PagedPool, sizeof(ACCESS_STATE));
|
AccessState = ExAllocatePool(PagedPool, sizeof(ACCESS_STATE));
|
||||||
PsProcessType = ExAllocatePool(PagedPool, sizeof(OBJECT_TYPE));
|
// AUX_ACCESS_DATA gets larger in newer Windows version.
|
||||||
AuxData = ExAllocatePool(PagedPool, 0xC8);
|
// This is the largest known size, found in Windows 10/11.
|
||||||
GenericMapping = ExAllocatePool(PagedPool, sizeof(GENERIC_MAPPING));
|
AuxData = ExAllocatePoolZero(PagedPool, 0xE0, 'QSmK');
|
||||||
|
|
||||||
Status = SeCreateAccessState(AccessState,
|
Status = SeCreateAccessState(AccessState,
|
||||||
(PVOID)AuxData,
|
AuxData,
|
||||||
DesiredAccess,
|
DesiredAccess,
|
||||||
GenericMapping
|
&ProcessGenericMapping
|
||||||
);
|
);
|
||||||
|
|
||||||
ok((Status == STATUS_SUCCESS), "SeCreateAccessState failed with Status 0x%08X\n", Status);
|
ok((Status == STATUS_SUCCESS), "SeCreateAccessState failed with Status 0x%08X\n", Status);
|
||||||
|
@ -267,43 +279,48 @@ START_TEST(SeQueryInfoToken)
|
||||||
// Testing SeAppendPrivileges //
|
// Testing SeAppendPrivileges //
|
||||||
//----------------------------------------------------------------//
|
//----------------------------------------------------------------//
|
||||||
|
|
||||||
AuxData->PrivilegeSet->PrivilegeCount = 1;
|
InitialPrivilegeCount = AuxData->PrivilegesUsed->PrivilegeCount;
|
||||||
|
trace("Initial privilege count = %lu\n", InitialPrivilegeCount);
|
||||||
|
|
||||||
// Testing SeAppendPrivileges. Must change PrivilegeCount to 2 (1 + 1)
|
// Testing SeAppendPrivileges. Must change PrivilegeCount to 2 (1 + 1)
|
||||||
|
|
||||||
NewPrivilegeSet = ExAllocatePool(PagedPool, sizeof(PRIVILEGE_SET));
|
NewPrivilegeSet = ExAllocatePoolZero(PagedPool,
|
||||||
|
FIELD_OFFSET(PRIVILEGE_SET, Privilege[1]),
|
||||||
|
'QSmK');
|
||||||
NewPrivilegeSet->PrivilegeCount = 1;
|
NewPrivilegeSet->PrivilegeCount = 1;
|
||||||
|
|
||||||
Status = SeAppendPrivileges(AccessState, NewPrivilegeSet);
|
Status = SeAppendPrivileges(AccessState, NewPrivilegeSet);
|
||||||
ok(Status == STATUS_SUCCESS, "SeAppendPrivileges failed\n");
|
ok(Status == STATUS_SUCCESS, "SeAppendPrivileges failed\n");
|
||||||
ok((AuxData->PrivilegeSet->PrivilegeCount == 2),"PrivelegeCount must be 2, but it is %d\n", AuxData->PrivilegeSet->PrivilegeCount);
|
ok_eq_ulong(AuxData->PrivilegesUsed->PrivilegeCount, InitialPrivilegeCount + 1);
|
||||||
ExFreePool(NewPrivilegeSet);
|
ExFreePoolWithTag(NewPrivilegeSet, 'QSmK');
|
||||||
|
|
||||||
//----------------------------------------------------------------//
|
//----------------------------------------------------------------//
|
||||||
|
|
||||||
// Testing SeAppendPrivileges. Must change PrivilegeCount to 6 (2 + 4)
|
// Testing SeAppendPrivileges. Must change PrivilegeCount to 6 (2 + 4)
|
||||||
|
|
||||||
NewPrivilegeSet = ExAllocatePool(PagedPool, 4*sizeof(PRIVILEGE_SET));
|
NewPrivilegeSet = ExAllocatePoolZero(PagedPool,
|
||||||
|
FIELD_OFFSET(PRIVILEGE_SET, Privilege[4]),
|
||||||
|
'QSmK');
|
||||||
NewPrivilegeSet->PrivilegeCount = 4;
|
NewPrivilegeSet->PrivilegeCount = 4;
|
||||||
|
|
||||||
Status = SeAppendPrivileges(AccessState, NewPrivilegeSet);
|
Status = SeAppendPrivileges(AccessState, NewPrivilegeSet);
|
||||||
ok(Status == STATUS_SUCCESS, "SeAppendPrivileges failed\n");
|
ok(Status == STATUS_SUCCESS, "SeAppendPrivileges failed\n");
|
||||||
ok((AuxData->PrivilegeSet->PrivilegeCount == 6),"PrivelegeCount must be 6, but it is %d\n", AuxData->PrivilegeSet->PrivilegeCount);
|
ok_eq_ulong(AuxData->PrivilegesUsed->PrivilegeCount, InitialPrivilegeCount + 5);
|
||||||
ExFreePool(NewPrivilegeSet);
|
ExFreePoolWithTag(NewPrivilegeSet, 'QSmK');
|
||||||
|
|
||||||
//----------------------------------------------------------------//
|
//----------------------------------------------------------------//
|
||||||
// Testing SePrivilegeCheck //
|
// Testing SePrivilegeCheck //
|
||||||
//----------------------------------------------------------------//
|
//----------------------------------------------------------------//
|
||||||
|
|
||||||
// KPROCESSOR_MODE is set to KernelMode ===> Always return TRUE
|
// KPROCESSOR_MODE is set to KernelMode ===> Always return TRUE
|
||||||
ok(SePrivilegeCheck(AuxData->PrivilegeSet, &(AccessState->SubjectSecurityContext), KernelMode), "SePrivilegeCheck failed with KernelMode mode arg\n");
|
ok(SePrivilegeCheck(AuxData->PrivilegesUsed, &(AccessState->SubjectSecurityContext), KernelMode), "SePrivilegeCheck failed with KernelMode mode arg\n");
|
||||||
// and call it again
|
// and call it again
|
||||||
ok(SePrivilegeCheck(AuxData->PrivilegeSet, &(AccessState->SubjectSecurityContext), KernelMode), "SePrivilegeCheck failed with KernelMode mode arg\n");
|
ok(SePrivilegeCheck(AuxData->PrivilegesUsed, &(AccessState->SubjectSecurityContext), KernelMode), "SePrivilegeCheck failed with KernelMode mode arg\n");
|
||||||
|
|
||||||
//----------------------------------------------------------------//
|
//----------------------------------------------------------------//
|
||||||
|
|
||||||
// KPROCESSOR_MODE is set to UserMode. Expect false
|
// KPROCESSOR_MODE is set to UserMode. Expect false
|
||||||
ok(!SePrivilegeCheck(AuxData->PrivilegeSet, &(AccessState->SubjectSecurityContext), UserMode), "SePrivilegeCheck unexpected success with UserMode arg\n");
|
ok(!SePrivilegeCheck(AuxData->PrivilegesUsed, &(AccessState->SubjectSecurityContext), UserMode), "SePrivilegeCheck unexpected success with UserMode arg\n");
|
||||||
|
|
||||||
//----------------------------------------------------------------//
|
//----------------------------------------------------------------//
|
||||||
|
|
||||||
|
@ -311,6 +328,10 @@ START_TEST(SeQueryInfoToken)
|
||||||
// Testing SeFreePrivileges //
|
// Testing SeFreePrivileges //
|
||||||
//----------------------------------------------------------------//
|
//----------------------------------------------------------------//
|
||||||
|
|
||||||
|
// FIXME: KernelMode will automatically get all access granted without
|
||||||
|
// getting Privileges filled in. For UserMode, Privileges will only get
|
||||||
|
// filled if either WRITE_OWNER or ACCESS_SYSTEM_SECURITY is requested
|
||||||
|
// and granted. So this doesn't really test SeFreePrivileges.
|
||||||
Privileges = NULL;
|
Privileges = NULL;
|
||||||
Checker = SeAccessCheck(
|
Checker = SeAccessCheck(
|
||||||
AccessState->SecurityDescriptor,
|
AccessState->SecurityDescriptor,
|
||||||
|
@ -319,17 +340,17 @@ START_TEST(SeQueryInfoToken)
|
||||||
AccessState->OriginalDesiredAccess,
|
AccessState->OriginalDesiredAccess,
|
||||||
AccessState->PreviouslyGrantedAccess,
|
AccessState->PreviouslyGrantedAccess,
|
||||||
&Privileges,
|
&Privileges,
|
||||||
(PGENERIC_MAPPING)((PCHAR*)PsProcessType + 52),
|
&ProcessGenericMapping,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
&AccessMask,
|
&AccessMask,
|
||||||
&Status
|
&Status
|
||||||
);
|
);
|
||||||
ok(Checker, "Checker is NULL\n");
|
ok(Checker, "Checker is NULL\n");
|
||||||
ok((Privileges != NULL), "Privileges is NULL\n");
|
ok(Privileges == NULL, "Privileges is not NULL\n");
|
||||||
if (Privileges)
|
if (Privileges)
|
||||||
{
|
{
|
||||||
trace("AuxData->PrivilegeSet->PrivilegeCount = %d ; Privileges->PrivilegeCount = %d\n",
|
trace("AuxData->PrivilegesUsed->PrivilegeCount = %d ; Privileges->PrivilegeCount = %d\n",
|
||||||
AuxData->PrivilegeSet->PrivilegeCount, Privileges->PrivilegeCount);
|
AuxData->PrivilegesUsed->PrivilegeCount, Privileges->PrivilegeCount);
|
||||||
}
|
}
|
||||||
if (Privileges) SeFreePrivileges(Privileges);
|
if (Privileges) SeFreePrivileges(Privileges);
|
||||||
|
|
||||||
|
@ -352,25 +373,29 @@ START_TEST(SeQueryInfoToken)
|
||||||
TPrivileges = (PTOKEN_PRIVILEGES)(Buffer);
|
TPrivileges = (PTOKEN_PRIVILEGES)(Buffer);
|
||||||
//trace("TPCount = %u\n\n", TPrivileges->PrivilegeCount);
|
//trace("TPCount = %u\n\n", TPrivileges->PrivilegeCount);
|
||||||
|
|
||||||
NewPrivilegeSet = ExAllocatePool(PagedPool, 14*sizeof(PRIVILEGE_SET));
|
NewPrivilegeSet = ExAllocatePoolZero(PagedPool,
|
||||||
|
FIELD_OFFSET(PRIVILEGE_SET, Privilege[14]),
|
||||||
|
'QSmK');
|
||||||
NewPrivilegeSet->PrivilegeCount = 14;
|
NewPrivilegeSet->PrivilegeCount = 14;
|
||||||
|
|
||||||
ok((SeAppendPrivileges(AccessState, NewPrivilegeSet)) == STATUS_SUCCESS, "SeAppendPrivileges failed\n");
|
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);
|
ok_eq_ulong(AuxData->PrivilegesUsed->PrivilegeCount, InitialPrivilegeCount + 19);
|
||||||
ExFreePool(NewPrivilegeSet);
|
ExFreePoolWithTag(NewPrivilegeSet, 'QSmK');
|
||||||
for (i = 0; i < AuxData->PrivilegeSet->PrivilegeCount; i++)
|
for (i = 0; i < AuxData->PrivilegesUsed->PrivilegeCount; i++)
|
||||||
{
|
{
|
||||||
AuxData->PrivilegeSet->Privilege[i].Attributes = TPrivileges->Privileges[i].Attributes;
|
AuxData->PrivilegesUsed->Privilege[i].Attributes = TPrivileges->Privileges[i].Attributes;
|
||||||
AuxData->PrivilegeSet->Privilege[i].Luid = TPrivileges->Privileges[i].Luid;
|
AuxData->PrivilegesUsed->Privilege[i].Luid = TPrivileges->Privileges[i].Luid;
|
||||||
}
|
}
|
||||||
//trace("AccessState->privCount = %u\n\n", ((PAUX_ACCESS_DATA)(AccessState->AuxData))->PrivilegeSet->PrivilegeCount);
|
//trace("AccessState->privCount = %u\n\n", ((PAUX_ACCESS_DATA)(AccessState->AuxData))->PrivilegesUsed->PrivilegeCount);
|
||||||
|
|
||||||
ok(SePrivilegeCheck(AuxData->PrivilegeSet, &(AccessState->SubjectSecurityContext), UserMode), "SePrivilegeCheck fails in UserMode, but I wish it will success\n");
|
ok(SePrivilegeCheck(AuxData->PrivilegesUsed, &(AccessState->SubjectSecurityContext), UserMode), "SePrivilegeCheck fails in UserMode, but I wish it will success\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call SeFreePrivileges again
|
// Call SeFreePrivileges again
|
||||||
|
|
||||||
|
// FIXME: See other SeAccessCheck call above, we're not really testing
|
||||||
|
// SeFreePrivileges here.
|
||||||
Privileges = NULL;
|
Privileges = NULL;
|
||||||
Checker = SeAccessCheck(
|
Checker = SeAccessCheck(
|
||||||
AccessState->SecurityDescriptor,
|
AccessState->SecurityDescriptor,
|
||||||
|
@ -379,17 +404,17 @@ START_TEST(SeQueryInfoToken)
|
||||||
AccessState->OriginalDesiredAccess,
|
AccessState->OriginalDesiredAccess,
|
||||||
AccessState->PreviouslyGrantedAccess,
|
AccessState->PreviouslyGrantedAccess,
|
||||||
&Privileges,
|
&Privileges,
|
||||||
(PGENERIC_MAPPING)((PCHAR*)PsProcessType + 52),
|
&ProcessGenericMapping,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
&AccessMask,
|
&AccessMask,
|
||||||
&Status
|
&Status
|
||||||
);
|
);
|
||||||
ok(Checker, "Checker is NULL\n");
|
ok(Checker, "Checker is NULL\n");
|
||||||
ok((Privileges != NULL), "Privileges is NULL\n");
|
ok(Privileges == NULL, "Privileges is not NULL\n");
|
||||||
if (Privileges)
|
if (Privileges)
|
||||||
{
|
{
|
||||||
trace("AuxData->PrivilegeSet->PrivilegeCount = %d ; Privileges->PrivilegeCount = %d\n",
|
trace("AuxData->PrivilegesUsed->PrivilegeCount = %d ; Privileges->PrivilegeCount = %d\n",
|
||||||
AuxData->PrivilegeSet->PrivilegeCount, Privileges->PrivilegeCount);
|
AuxData->PrivilegesUsed->PrivilegeCount, Privileges->PrivilegeCount);
|
||||||
}
|
}
|
||||||
if (Privileges) SeFreePrivileges(Privileges);
|
if (Privileges) SeFreePrivileges(Privileges);
|
||||||
|
|
||||||
|
@ -402,9 +427,7 @@ START_TEST(SeQueryInfoToken)
|
||||||
|
|
||||||
SeDeleteAccessState(AccessState);
|
SeDeleteAccessState(AccessState);
|
||||||
|
|
||||||
if (GenericMapping) ExFreePool(GenericMapping);
|
|
||||||
if (PsProcessType) ExFreePool(PsProcessType);
|
|
||||||
if (SubjectContext) ExFreePool(SubjectContext);
|
if (SubjectContext) ExFreePool(SubjectContext);
|
||||||
if (AuxData) ExFreePool(AuxData);
|
if (AuxData) ExFreePoolWithTag(AuxData, 'QSmK');
|
||||||
if (AccessState) ExFreePool(AccessState);
|
if (AccessState) ExFreePool(AccessState);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1647,8 +1647,8 @@ ObpCreateHandle(IN OB_OPEN_REASON OpenReason,
|
||||||
if (OpenReason == ObCreateHandle)
|
if (OpenReason == ObCreateHandle)
|
||||||
{
|
{
|
||||||
/* Check if we need to audit the privileges */
|
/* Check if we need to audit the privileges */
|
||||||
if ((AuxData->PrivilegeSet) &&
|
if ((AuxData->PrivilegesUsed) &&
|
||||||
(AuxData->PrivilegeSet->PrivilegeCount))
|
(AuxData->PrivilegesUsed->PrivilegeCount))
|
||||||
{
|
{
|
||||||
/* Do the audit */
|
/* Do the audit */
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -1656,7 +1656,7 @@ ObpCreateHandle(IN OB_OPEN_REASON OpenReason,
|
||||||
&AccessState->
|
&AccessState->
|
||||||
SubjectSecurityContext,
|
SubjectSecurityContext,
|
||||||
GrantedAccess,
|
GrantedAccess,
|
||||||
AuxData->PrivilegeSet,
|
AuxData->PrivilegesUsed,
|
||||||
TRUE,
|
TRUE,
|
||||||
ExGetPreviousMode());
|
ExGetPreviousMode());
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,10 +23,10 @@
|
||||||
* @param[in] Process
|
* @param[in] Process
|
||||||
* Valid process object where subject context is to be captured.
|
* Valid process object where subject context is to be captured.
|
||||||
*
|
*
|
||||||
* @param[in,out] AccessState
|
* @param[out] AccessState
|
||||||
* An initialized returned parameter to an access state.
|
* An initialized returned parameter to an access state.
|
||||||
*
|
*
|
||||||
* @param[in] AuxData
|
* @param[out] AuxData
|
||||||
* Auxiliary security data for access state.
|
* Auxiliary security data for access state.
|
||||||
*
|
*
|
||||||
* @param[in] Access
|
* @param[in] Access
|
||||||
|
@ -43,8 +43,8 @@ NTAPI
|
||||||
SeCreateAccessStateEx(
|
SeCreateAccessStateEx(
|
||||||
_In_ PETHREAD Thread,
|
_In_ PETHREAD Thread,
|
||||||
_In_ PEPROCESS Process,
|
_In_ PEPROCESS Process,
|
||||||
_Inout_ PACCESS_STATE AccessState,
|
_Out_ PACCESS_STATE AccessState,
|
||||||
_In_ PAUX_ACCESS_DATA AuxData,
|
_Out_ __drv_aliasesMem PAUX_ACCESS_DATA AuxData,
|
||||||
_In_ ACCESS_MASK Access,
|
_In_ ACCESS_MASK Access,
|
||||||
_In_ PGENERIC_MAPPING GenericMapping)
|
_In_ PGENERIC_MAPPING GenericMapping)
|
||||||
{
|
{
|
||||||
|
@ -88,7 +88,7 @@ SeCreateAccessStateEx(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the Auxiliary Data */
|
/* Set the Auxiliary Data */
|
||||||
AuxData->PrivilegeSet = (PPRIVILEGE_SET)((ULONG_PTR)AccessState +
|
AuxData->PrivilegesUsed = (PPRIVILEGE_SET)((ULONG_PTR)AccessState +
|
||||||
FIELD_OFFSET(ACCESS_STATE,
|
FIELD_OFFSET(ACCESS_STATE,
|
||||||
Privileges));
|
Privileges));
|
||||||
if (GenericMapping) AuxData->GenericMapping = *GenericMapping;
|
if (GenericMapping) AuxData->GenericMapping = *GenericMapping;
|
||||||
|
@ -101,10 +101,10 @@ SeCreateAccessStateEx(
|
||||||
* @brief
|
* @brief
|
||||||
* Creates an access state.
|
* Creates an access state.
|
||||||
*
|
*
|
||||||
* @param[in,out] AccessState
|
* @param[out] AccessState
|
||||||
* An initialized returned parameter to an access state.
|
* An initialized returned parameter to an access state.
|
||||||
*
|
*
|
||||||
* @param[in] AuxData
|
* @param[out] AuxData
|
||||||
* Auxiliary security data for access state.
|
* Auxiliary security data for access state.
|
||||||
*
|
*
|
||||||
* @param[in] Access
|
* @param[in] Access
|
||||||
|
@ -119,8 +119,8 @@ SeCreateAccessStateEx(
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
SeCreateAccessState(
|
SeCreateAccessState(
|
||||||
_Inout_ PACCESS_STATE AccessState,
|
_Out_ PACCESS_STATE AccessState,
|
||||||
_In_ PAUX_ACCESS_DATA AuxData,
|
_Out_ __drv_aliasesMem PAUX_ACCESS_DATA AuxData,
|
||||||
_In_ ACCESS_MASK Access,
|
_In_ ACCESS_MASK Access,
|
||||||
_In_ PGENERIC_MAPPING GenericMapping)
|
_In_ PGENERIC_MAPPING GenericMapping)
|
||||||
{
|
{
|
||||||
|
@ -158,7 +158,7 @@ SeDeleteAccessState(
|
||||||
|
|
||||||
/* Deallocate Privileges */
|
/* Deallocate Privileges */
|
||||||
if (AccessState->PrivilegesAllocated)
|
if (AccessState->PrivilegesAllocated)
|
||||||
ExFreePoolWithTag(AuxData->PrivilegeSet, TAG_PRIVILEGE_SET);
|
ExFreePoolWithTag(AuxData->PrivilegesUsed, TAG_PRIVILEGE_SET);
|
||||||
|
|
||||||
/* Deallocate Name and Type Name */
|
/* Deallocate Name and Type Name */
|
||||||
if (AccessState->ObjectName.Buffer)
|
if (AccessState->ObjectName.Buffer)
|
||||||
|
|
|
@ -601,9 +601,9 @@ SeAppendPrivileges(
|
||||||
|
|
||||||
/* Calculate the size of the old privilege set */
|
/* Calculate the size of the old privilege set */
|
||||||
OldPrivilegeSetSize = sizeof(PRIVILEGE_SET) +
|
OldPrivilegeSetSize = sizeof(PRIVILEGE_SET) +
|
||||||
(AuxData->PrivilegeSet->PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES);
|
(AuxData->PrivilegesUsed->PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES);
|
||||||
|
|
||||||
if (AuxData->PrivilegeSet->PrivilegeCount +
|
if (AuxData->PrivilegesUsed->PrivilegeCount +
|
||||||
Privileges->PrivilegeCount > INITIAL_PRIVILEGE_COUNT)
|
Privileges->PrivilegeCount > INITIAL_PRIVILEGE_COUNT)
|
||||||
{
|
{
|
||||||
/* Calculate the size of the new privilege set */
|
/* Calculate the size of the new privilege set */
|
||||||
|
@ -619,7 +619,7 @@ SeAppendPrivileges(
|
||||||
|
|
||||||
/* Copy original privileges from the acess state */
|
/* Copy original privileges from the acess state */
|
||||||
RtlCopyMemory(PrivilegeSet,
|
RtlCopyMemory(PrivilegeSet,
|
||||||
AuxData->PrivilegeSet,
|
AuxData->PrivilegesUsed,
|
||||||
OldPrivilegeSetSize);
|
OldPrivilegeSetSize);
|
||||||
|
|
||||||
/* Append privileges from the privilege set*/
|
/* Append privileges from the privilege set*/
|
||||||
|
@ -632,23 +632,23 @@ SeAppendPrivileges(
|
||||||
|
|
||||||
/* Free the old privilege set if it was allocated */
|
/* Free the old privilege set if it was allocated */
|
||||||
if (AccessState->PrivilegesAllocated != FALSE)
|
if (AccessState->PrivilegesAllocated != FALSE)
|
||||||
ExFreePoolWithTag(AuxData->PrivilegeSet, TAG_PRIVILEGE_SET);
|
ExFreePoolWithTag(AuxData->PrivilegesUsed, TAG_PRIVILEGE_SET);
|
||||||
|
|
||||||
/* Now we are using an allocated privilege set */
|
/* Now we are using an allocated privilege set */
|
||||||
AccessState->PrivilegesAllocated = TRUE;
|
AccessState->PrivilegesAllocated = TRUE;
|
||||||
|
|
||||||
/* Assign the new privileges to the access state */
|
/* Assign the new privileges to the access state */
|
||||||
AuxData->PrivilegeSet = PrivilegeSet;
|
AuxData->PrivilegesUsed = PrivilegeSet;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Append privileges */
|
/* Append privileges */
|
||||||
RtlCopyMemory((PVOID)((ULONG_PTR)AuxData->PrivilegeSet + OldPrivilegeSetSize),
|
RtlCopyMemory((PVOID)((ULONG_PTR)AuxData->PrivilegesUsed + OldPrivilegeSetSize),
|
||||||
(PVOID)((ULONG_PTR)Privileges + sizeof(PRIVILEGE_SET) - sizeof(LUID_AND_ATTRIBUTES)),
|
(PVOID)((ULONG_PTR)Privileges + sizeof(PRIVILEGE_SET) - sizeof(LUID_AND_ATTRIBUTES)),
|
||||||
Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
|
Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
|
||||||
|
|
||||||
/* Adjust the number of privileges in the target privilege set */
|
/* Adjust the number of privileges in the target privilege set */
|
||||||
AuxData->PrivilegeSet->PrivilegeCount += Privileges->PrivilegeCount;
|
AuxData->PrivilegesUsed->PrivilegeCount += Privileges->PrivilegeCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
|
@ -255,9 +255,24 @@ typedef struct _TOKEN
|
||||||
|
|
||||||
typedef struct _AUX_ACCESS_DATA
|
typedef struct _AUX_ACCESS_DATA
|
||||||
{
|
{
|
||||||
PPRIVILEGE_SET PrivilegeSet;
|
PPRIVILEGE_SET PrivilegesUsed;
|
||||||
GENERIC_MAPPING GenericMapping;
|
GENERIC_MAPPING GenericMapping;
|
||||||
ULONG Reserved;
|
ACCESS_MASK AccessesToAudit;
|
||||||
|
ACCESS_MASK MaximumAuditMask;
|
||||||
|
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
|
||||||
|
GUID TransactionId;
|
||||||
|
#endif
|
||||||
|
#if (NTDDI_VERSION >= NTDDI_WIN7)
|
||||||
|
PVOID NewSecurityDescriptor;
|
||||||
|
PVOID ExistingSecurityDescriptor;
|
||||||
|
PVOID ParentSecurityDescriptor;
|
||||||
|
VOID (NTAPI *DerefSecurityDescriptor)(PVOID, PVOID);
|
||||||
|
PVOID SDLock;
|
||||||
|
ACCESS_REASONS AccessReasons;
|
||||||
|
#endif
|
||||||
|
#if (NTDDI_VERSION >= NTDDI_WIN8)
|
||||||
|
BOOLEAN GenerateStagingEvents;
|
||||||
|
#endif
|
||||||
} AUX_ACCESS_DATA, *PAUX_ACCESS_DATA;
|
} AUX_ACCESS_DATA, *PAUX_ACCESS_DATA;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue