[NTOS:OB] Properly calculate the return length in ObQueryTypeInfo On a x86 system aligning the return length pointer to a 4-byte boundary works best since pointers in general are 4-byte aligned for x86 systems. However, what happens on a AMD64 system is that we still align this pointer to 4-byte, ObjectTypeInfo is a 8-byte pointer and we might write into the return length past the 4-byte boundary. If one were to allocate a pool of memory with that length and query all the object types info and free the said pool of memory thereafter, the system will crash with BAD_POOL_HEADER because ObQueryTypeInfo overwrote the return length past the 4-byte boundary length therefore leading up with corrupted memory blocks in the pool header. This symptom of BAD_POOL_HEADER happens exactly the same in Windows Server 2003 x64 Edition. Newer versions of Windows like 10 aren't affected. But, Windows has another bug where they are using MaximumLength for the calculation of the needed length to be returned to caller. MaximumLength does not guarantee you that it includes the NULL-terminator in the length and that potentially leads to a buffer overrun. Also annotate the ObQueryTypeInfo function with SAL2. https://processhacker.sourceforge.io/doc/object_8c_source.html (read the comment in KphObjectTypeInformation).
[NTOS:OB] Implement name information querying on ObjectBasicInformation case Currently there is no implementation support for object name information querying when someone queries information about an object with ObjectBasicInformation class case. Some device drivers may take use of such information. NameInfoSize is a size that is the sum of all name directories of an object, including path separators. TypeInfoSize is a size that is pointed by the size of a type object itself, therefore this size remains pretty much fixed depending on the kind of an object. For more information: https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntobapi/object_basic_information.htm http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FNT%20Objects%2FType%20independed%2FNtQueryObject.html
[NTOS:OB] Include the security descriptor charge when charging the paged pool quota of an object On ObpChargeQuotaForObject function, the kernel will either charge the default object type charges or the specified information charges obtained from ObCreateObject API call. What happens is that if a paged pool charge is specified on ObCreateObject call the kernel will charge that but when an object is about to be de-allocated, the amount of quota to return back to the system is the amounting of the paged pool charge specified previously by the ObCreateObject call plus the amounting of the security descriptor charge (see oblife.c / line 98). This will result in a fatal crash with a bugcheck of QUOTA_UNDERFLOW because we are returning quota with bits of it that was never charged and that's SecurityDescriptorCharge. A QUOTA_UNDERFLOW bugcheck occurs in two following scenarios: -- When installing Virtualbox Guest Additions and prompting the installer to reboot the system for you -- When logging off and on back to the system and then you restart the system normally This bug has been discovered whilst working on #4555 PR.
[NTOS:OB] Specify the query security descriptor tag when freeing the allocation We are allocating blocks of pool memory for a security descriptor with its own specific tag, TAG_SEC_QUERY, so just use it when freeing when releasing the descriptor as well (aka freeing the said pool).
[NTOS:OB] Charge/Return pool quotas of objects As it currently stands the Object Manager doesn't charge any quotas when objects are created, nor it returns quotas when objects are de-allocated and freed from the objects namespace database. This alone can bring inconsistencies in the kernel as we simply don't know what is the amount charged in an object and thus we aren't keeping track of quotas flow. Now with both PsReturnSharedPoolQuota and PsChargeSharedPoolQuota implemented, the Object Manager can now track the said flow of quotas every time an object is created or de-allocated, thus enforcing consistency with the use of quota resources.
[NTOS:OB] Minor refactoring. - NtQuerySymbolicLinkObject(): Use an intermediate variable for the object header. - Simplify code in ObpLookupEntryDirectory() by calling ObpReleaseLookupContextObject() instead. - Use TAG_OBJECT_TYPE instead of hardcoded tag values.
[NTOS:OB] Clarify and fix the usage of the Obp*DirectoryLock*() and ObpReleaseLookupContextObject() functions. - Disentangle the usage of ObpAcquireDirectoryLockExclusive() when it's used only for accessing a directory structure, or as part of a lookup operation. The Obp*DirectoryLock*() -- both shared and exclusive -- functions are only for locking an OB directory, for reading or writing its structure members. When performing lookup operations (insertions/deletions of entries within a directory), use a ObpAcquireLookupContextLock() function that exclusively locks the directory and saves extra lock state, that can be used by ObpReleaseLookupContextObject() for cleanup. - Add documentation for these functions.
[NTOS:OB] Do not close the handle if it's granted access to ObpAccessProtectCloseBit As of now the Object Manager private service, ObpCloseHandleTableEntry, looks for OBJ_PROTECT_CLOSE attribute if a handle should not be closed. However, in ObDuplicateObject if an attribute of OBJ_PROTECT_CLOSE is found as it's been filled to the caller (see L2466) this attribute is removed from the attributes list of the new handle and ObpAccessProtectCloseBit access is granted to the newly duplicated object handle. With that being said ObpCloseHandleTableEntry indiscriminately closes the object handle albeit it shouldn't do so. As a matter of fact in Windows Server 2003 SP2 this service indeed checks for ObpAccessProtectCloseBit flag bit and if the condition is met then it returns STATUS_HANDLE_NOT_CLOSABLE as it should. Therefore we should do the same. Now NtClose can properly warn the calling thread the object handle can't be closed which fixes a testcase failure within NtDuplicateObject NTDLL APITEST where this function gives handle close protection bit as requested by the caller.
[REACTOS] Cleanup INIT and some PAGE section allocations - Change INIT_FUNCTION and INIT_SECTION to CODE_SEG("INIT") and DATA_SEG("INIT") respectively - Remove INIT_FUNCTION from function prototypes - Remove alloc_text pragma calls as they are not needed anymore
[NTOSKRNL] Sync some INIT_FUNCTION (#2824) - Sync some INIT_FUNCTION with how they are used and what is already specified in the headers. Addendum to commit 85e5b5be (r49445). - KdbpGetCommandLineSettings(): Remove INIT_FUNCTION. Fix MSVC 2015 x86 custom build: "...\ntoskrnl\kdbg\kdb.c(1699): error C2983: 'KdbpGetCommandLineSettings': all declarations must have an identical __declspec(code_seg(...))" And may also fix obscure bugs when entering into the KDBG debugger.