https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1fd730b78115ca0e55335…
commit 1fd730b78115ca0e55335a0204061c83e48e53c3
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Fri Jun 11 01:30:40 2021 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Sep 5 20:31:08 2021 +0200
[NTOS:IO] IopInitializeDriverModule(): Set the DRVO_LEGACY_DRIVER flag if the driver is not WDM. (#3749)
---
ntoskrnl/io/iomgr/driver.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/ntoskrnl/io/iomgr/driver.c b/ntoskrnl/io/iomgr/driver.c
index a5ab9904bb4..eb3817b98ec 100644
--- a/ntoskrnl/io/iomgr/driver.c
+++ b/ntoskrnl/io/iomgr/driver.c
@@ -447,6 +447,16 @@ IopInitializeDriverModule(
DPRINT("Driver name: '%wZ'\n", &DriverName);
+ /*
+ * Retrieve the driver's PE image NT header and perform some sanity checks.
+ * NOTE: We suppose that since the driver has been successfully loaded,
+ * its NT and optional headers are all valid and have expected sizes.
+ */
+ PIMAGE_NT_HEADERS NtHeaders = RtlImageNtHeader(ModuleObject->DllBase);
+ ASSERT(NtHeaders);
+ ASSERT(ModuleObject->SizeOfImage == NtHeaders->OptionalHeader.SizeOfImage);
+ ASSERT(ModuleObject->EntryPoint == RVA(ModuleObject->DllBase, NtHeaders->OptionalHeader.AddressOfEntryPoint));
+
/* Obtain the registry path for the DriverInit routine */
PKEY_NAME_INFORMATION nameInfo;
ULONG infoLength;
@@ -524,7 +534,11 @@ IopInitializeDriverModule(
RtlZeroMemory(driverObject, ObjectSize);
driverObject->Type = IO_TYPE_DRIVER;
driverObject->Size = sizeof(DRIVER_OBJECT);
- driverObject->Flags = DRVO_LEGACY_DRIVER; // TODO: check the WDM_DRIVER flag on the module
+
+ /* Set the legacy flag if this is not a WDM driver */
+ if (!(NtHeaders->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_WDM_DRIVER))
+ driverObject->Flags |= DRVO_LEGACY_DRIVER;
+
driverObject->DriverSection = ModuleObject;
driverObject->DriverStart = ModuleObject->DllBase;
driverObject->DriverSize = ModuleObject->SizeOfImage;
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c407460f6af9e6d10913c…
commit c407460f6af9e6d10913c48616646e2aa2e3f6b6
Author: George Bișoc <george.bisoc(a)reactos.org>
AuthorDate: Tue Aug 31 12:34:25 2021 +0200
Commit: George Bișoc <george.bisoc(a)reactos.org>
CommitDate: Sun Sep 5 17:01:21 2021 +0200
[NTOS:SE] Implement effective token option upon duplication
This implements the EffectiveOnly option of SepDuplicateToken routine (used by NtDuplicateToken syscall and other functions alike) which makes the access token effective by removing the disabled parts like privileges and groups.
---
ntoskrnl/se/token.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 95 insertions(+), 5 deletions(-)
diff --git a/ntoskrnl/se/token.c b/ntoskrnl/se/token.c
index bef3d5a2bcf..73d70263e52 100644
--- a/ntoskrnl/se/token.c
+++ b/ntoskrnl/se/token.c
@@ -598,6 +598,43 @@ SepRemovePrivilegeToken(
Token->PrivilegeCount--;
}
+/**
+ * @brief
+ * Removes a group from the token.
+ *
+ * @param[in,out] Token
+ * The token where the group is to be removed.
+ *
+ * @param[in] Index
+ * The index count which represents the number position of the group
+ * we want to remove.
+ *
+ * @return
+ * Nothing.
+ */
+static
+VOID
+SepRemoveUserGroupToken(
+ _Inout_ PTOKEN Token,
+ _In_ ULONG Index)
+{
+ ULONG MoveCount;
+ ASSERT(Index < Token->UserAndGroupCount);
+
+ /* Calculate the number of trailing groups */
+ MoveCount = Token->UserAndGroupCount - Index - 1;
+ if (MoveCount != 0)
+ {
+ /* Time to remove the group by moving one location ahead */
+ RtlMoveMemory(&Token->UserAndGroups[Index],
+ &Token->UserAndGroups[Index + 1],
+ MoveCount * sizeof(SID_AND_ATTRIBUTES));
+ }
+
+ /* Remove one group count */
+ Token->UserAndGroupCount--;
+}
+
/**
* @unimplemented
* @brief
@@ -969,6 +1006,7 @@ SepDuplicateToken(
PVOID EndMem;
ULONG VariableLength;
ULONG TotalSize;
+ ULONG PrivilegesIndex, GroupsIndex;
PAGED_CODE();
@@ -1141,12 +1179,64 @@ SepDuplicateToken(
}
}
+ /*
+ * Filter the token by removing the disabled privileges
+ * and groups if the caller wants to duplicate an access
+ * token as effective only.
+ */
+ if (EffectiveOnly)
+ {
+ /* Begin querying the groups and search for disabled ones */
+ for (GroupsIndex = 0; GroupsIndex < AccessToken->UserAndGroupCount; GroupsIndex++)
+ {
+ /*
+ * A group or user is considered disabled if its attributes is either
+ * 0 or SE_GROUP_ENABLED is not included in the attributes flags list.
+ * That is because a certain user and/or group can have several attributes
+ * that bear no influence on whether a user/group is enabled or not
+ * (SE_GROUP_ENABLED_BY_DEFAULT for example which is a mere indicator
+ * that the group has just been enabled by default). A mandatory
+ * group (that is, the group has SE_GROUP_MANDATORY attribute)
+ * by standards it's always enabled and no one can disable it.
+ */
+ if (AccessToken->UserAndGroups[GroupsIndex].Attributes == 0 ||
+ (AccessToken->UserAndGroups[GroupsIndex].Attributes & SE_GROUP_ENABLED) == 0)
+ {
+ /*
+ * A group is not enabled, it's time to remove
+ * from the token and update the groups index
+ * accordingly and continue with the next group.
+ */
+ SepRemoveUserGroupToken(AccessToken, GroupsIndex);
+ GroupsIndex--;
+ }
+ }
- //
- // FIXME: Implement the "EffectiveOnly" option, that removes all
- // the disabled parts (privileges and groups) of the token.
- //
-
+ /* Begin querying the privileges and search for disabled ones */
+ for (PrivilegesIndex = 0; PrivilegesIndex < AccessToken->PrivilegeCount; PrivilegesIndex++)
+ {
+ /*
+ * A privilege is considered disabled if its attributes is either
+ * 0 or SE_PRIVILEGE_ENABLED is not included in the attributes flags list.
+ * That is because a certain privilege can have several attributes
+ * that bear no influence on whether a privilege is enabled or not
+ * (SE_PRIVILEGE_ENABLED_BY_DEFAULT for example which is a mere indicator
+ * that the privilege has just been enabled by default).
+ */
+ if (AccessToken->Privileges[PrivilegesIndex].Attributes == 0 ||
+ (AccessToken->Privileges[PrivilegesIndex].Attributes & SE_PRIVILEGE_ENABLED) == 0)
+ {
+ /*
+ * A privilege is not enabled, therefor it's time
+ * to strip it from the token and continue with the next
+ * privilege. Of course we must also want to update the
+ * privileges index accordingly.
+ */
+ SepRemovePrivilegeToken(AccessToken, PrivilegesIndex);
+ PrivilegesIndex--;
+ }
+ }
+ }
//
// NOTE: So far our dynamic area only contains