Commit graph

10 commits

Author SHA1 Message Date
George Bișoc
8b75dce45a
[NTOS:SE][FORMATTING] Fix the file header
This fixes the copyright file header at the top of the file, reflecting
the Coding Style rules. No code changes!
2023-03-07 18:39:46 +01:00
George Bișoc
3b00f98b94
[NTOS:SE] Fix new dynamic length calculation in TokenPrimaryGroup case
Not only primary group assignation was broken but new dynamic length calculation is also broken. The length of the captured SID is not taken into account so the new dynamic length gets only the size of the default ACL present in an access token.
Therefore, the condition is always FALSE and the code never jumps to the STATUS_ALLOTTED_SPACE_EXCEEDED branch because the length will always be small than the charged dynamic length.

Addendum to 86bde3c.
2022-08-16 20:27:27 +02:00
George Bișoc
86bde3c76a
[NTOS:SE] Fix the primary group assignation in TokenPrimaryGroup class case
With current master, what happens is that when someone wants to assign a new primary group SID for an access token, it results in an instant page fault because the primary group variable doesn't get assigned the dynamic part's address.
So the primary group variable gets an address which is basically a representation of the ACL size, hence the said address is bogus and it's where the page fault kicks in.

CORE-18249
2022-08-16 13:05:44 +02:00
George Bișoc
4471ee4dfa
[NTOS:SE] Properly handle dynamic counters in token
On current master, ReactOS faces these problems:

- ObCreateObject charges both paged and non paged pool a size of TOKEN structure, not the actual dynamic contents of WHAT IS inside a token. For paged pool charge the size is that of the dynamic area (primary group + default DACL if any). This is basically what DynamicCharged is for.
For the non paged pool charge, the actual charge is that of TOKEN structure upon creation. On duplication and filtering however, the paged pool charge size is that of the inherited dynamic charged space from an existing token whereas the non paged pool size is that of the calculated token body
length for the new duplicated/filtered token. On current master, we're literally cheating the kernel by charging the wrong amount of quota not taking into account the dynamic contents which they come from UM.

- Both DynamicCharged and DynamicAvailable are not fully handled (DynamicAvailable is pretty much poorly handled with some cases still to be taking into account). DynamicCharged is barely handled, like at all.

- As a result of these two points above, NtSetInformationToken doesn't check when the caller wants to set up a new default token DACL or primary group if the newly DACL or the said group exceeds the dynamic charged boundary. So what happens is that I'm going to act like a smug bastard fat politician and whack
the primary group and DACL of an token however I want to, because why in the hell not? In reality no, the kernel has to punish whoever attempts to do that, although we currently don't.

- The dynamic area (aka DynamicPart) only picks up the default DACL but not the primary group as well. Generally the dynamic part is composed of primary group and default DACL, if provided.

In addition to that, we aren't returning the dynamic charged and available area in token statistics. SepComputeAvailableDynamicSpace helper is here to accommodate that. Apparently Windows is calculating the dynamic available area rather than just querying the DynamicAvailable field directly from the token.
My theory regarding this is like the following: on Windows both TokenDefaultDacl and TokenPrimaryGroup classes are barely used by the system components during startup (LSASS provides both a DACL and primary group when calling NtCreateToken anyway). In fact DynamicAvailable is 0 during token creation, duplication and filtering when inspecting a token with WinDBG. So
if an application wants to query token statistics that application will face a dynamic available space of 0.
2022-06-29 10:06:37 +02:00
George Bișoc
9d2de519b2
[NTOS:SE] NtQueryInformationToken: implement TokenGroupsAndPrivileges
TokenGroupsAndPrivileges is the younger sister of two TokenGroups and TokenPrivileges classes. In its purpose there's no huge substantial differences apart that this class comes with its own structure, TOKEN_GROUPS_AND_PRIVILEGES, and that this structure comes with extra information.
2022-06-19 17:22:04 +02:00
George Bișoc
8e0da736b7
[NTOS:SE] Fix MSVC build 2022-06-13 20:12:32 +02:00
George Bișoc
93381263a1
[NTOS:SE] Remove redundant ReturnLength NULL check
In NtQueryInformationToken function, remove the useless and redundant NULL check for two primary reasons. First, DefaultQueryInfoBufferCheck already does the necessary probing validation checks and second, ReturnLength must NEVER be NULL!
If the caller does not respect the calling rules of NtQueryInformationToken, the caller is expected to be miserably punished.
2022-06-13 19:28:12 +02:00
George Bișoc
5e1f292062
[NTOS:SE] NtQueryInformationToken: implement token sandbox inert querying 2022-06-13 18:17:10 +02:00
George Bișoc
d0d86ab588
[NTOSKRNL] Force a probe against ReturnLength on query & Misc ICIF stuff
NtQueryInformationToken is by far the only system call in NT where ReturnLength simply cannot be optional. On Windows this parameter is always probed and an argument to NULL directly leads to an access violation exception.
This is due to the fact of how tokens work, as its information contents (token user, owner, primary group, et al) are dynamic and can vary throughout over time in memory.

What happens on current ReactOS master however is that ReturnLength is only probed if the parameter is not NULL. On a NULL case scenario the probing checks succeed and NtQueryInformationToken fails later. For this, just get rid of CompleteProbing
parameter and opt in for a bit mask flag based approach, with ICIF_FORCE_RETURN_LENGTH_PROBE being set on DefaultQueryInfoBufferCheck which NtQueryInformationToken calls it to do sanity checks.

In addition to that...

- Document the ICIF probe helpers
- Annotate the ICIF prope helpers with SAL
- With the riddance of CompleteProbing and adoption of flags based approach, add ICIF_PROBE_READ_WRITE and ICIF_PROBE_READ flags alongside with ICIF_FORCE_RETURN_LENGTH_PROBE
2022-06-12 11:05:05 +02:00
George Bișoc
9a2c62b544
[NTOS:SE] Reorganize the security manager component
The current state of Security manager's code is kind of a mess. Mainly, there's code scattered around places where they shouldn't belong and token implementation (token.c) is already of a bloat in itself as it is. The file has over 6k lines and it's subject to grow exponentially with improvements, features, whatever that is.

With that being said, the token implementation code in the kernel will be split accordingly and rest of the code moved to appropriate places. The new layout will look as follows (excluding the already existing files):

- client.c (Client security implementation code)
- objtype.c (Object type list implementation code -- more code related to object types will be put here when I'm going to implement object type access checks in the future)
- subject.c (Subject security context support)

The token implementation in the kernel will be split in 4 distinct files as shown:

- token.c (Base token support routines)
- tokenlif.c (Life management of a token object -- that is Duplication, Creation and Filtering)
- tokencls.c (Token Query/Set Information Classes support)
- tokenadj.c (Token privileges/groups adjusting support)

In addition to that, tidy up the internal header and reorganize it as well.
2022-05-29 20:22:19 +02:00