reactos/ntoskrnl/ob/obref.c

710 lines
21 KiB
C
Raw Normal View History

/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ob/obref.c
* PURPOSE: Manages the referencing and de-referencing of all Objects,
* as well as the Object Fast Reference implementation.
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
* Eric Kohl
* Thomas Weidenmueller (w3seek@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
[0.4.7][CDFS_NEW/NTOSKRNL/NDK] Switch from our old CDFS to MS-PL CDFS_NEW The main motivation to switch to that newer driver is, that our old one simply can not read all isos. Especially complex ones made trouble and were only shown as empty in explorer. It is still possible to build and use the old driver when needed, only thing that needs to be done for that is to revert 0.4.8-dev-164-g ec6b3ecbe48ad51c366563196cc93a6ae74e8b69 Porting back the state up to 0.4.8-release-100-g8f947b5 implies: Fixing the following JIRA-IDs (or avoid introducing them): CORE-18029 "Mute noisy DPRINT 'SectionObject has ImageSection'" CORE-17405 "Fix a macro-copy-paste and shrink the binary size" CORE-15659 "Unable to build the gcc Release version in Windows using RosBE 2.1.6 (module cdfs fails)" CORE-14315 "CDFS_NEW assertion during first stage setup due to new CcPerformReadAhead" CORE-14128 "Avast! Free Antivirus 7.0 hangs the system when trying to detect a newly created virus" CORE-14067 "CDFS_NEW assertions and exceptions" CORE-14003 "Shutting down LiveCD asserts since introduction of MS PL CDFS_NEW" CORE-13184 "Restore ability to install from disk-image" by picking the following commits: 0.4.8-release-100-g 8f947b532221069d2f398e25a9c0775c34e21878 [NTOSKRNL] Mute noisy DPRINT 'SectionObject has ImageSection' CORE-18029 0.4.8-release-80-g eb1ea195888e17d026428dc6f406a1834c8702d8 [CDFS_NEW] == 0.4.15-dev-1456-g 889eab7 CORE-17405 0.4.8-release-62-g 8c07aad4a8c6469c7e4ba4c5e92e356a6548189a [CDFS_NEW/XDK] == 0.4.11-dev-39-g a2f9762 + 0.4.11-dev-40-g 6d7ec8c CORE-14067 0.4.8-release-3-g 5d976d04e876aac6990a8f997669711eca83227a [CDFS_NEW] == 0.4.12-dev-431-g bccad87f3ccf266be2179d1322e7a422aeb2f3b7 + 0.4.12-dev-432-g 3463b2db9fc08e5ebe2f5b146d3fe12248f632f3 CORE-15659 0.4.8-RC-3-g 51f9494d484bbe8232e375c2693851316d9d530f [CDFS_NEW] superseded later by the proper fix 0.4.8-release-62-g 8c07aad4a8c6469c7e4ba4c5e92e356a6548189a CORE-14067 0.4.8-dev-1069-g a5e89014dc943b2cbddb16fc4d92e13b7e5068e1 [CDFS_NEW] CORE-14315 0.4.8-dev-475-g a59d4674dec116a951392bb6d136bd11f0e143f2 [NTOSKRNL] io/iomgr/device.c (forgotten assert) CORE-14128 0.4.8-dev-221-g 9d67a24799e29e832933311a8e6ba21787e40f6a [CDFS_NEW] 0.4.8-dev-220-g 67a7e45e351b70356fee442c31cb5de14a0de37e [CDFS_NEW/DOC] 0.4.8-dev-219-g 6a3bbf24e012e4985b97ca4d79604c28fe0133d7 [CDFS_NEW] 0.4.8-dev-218-g ec26cde4a13b3889883d3e1b19f7878179c76df5 [CDFS_NEW] 0.4.8-dev-217-g bc2378a3560a384c47d2a4c83886531ad8f0af90 [CDFS_NEW] 0.4.8-dev-216-g 5429771b9936a6d8aee6ffb3860310673f467e93 [CDFS_NEW] 0.4.8-dev-215-g fd345482634d8ef4c64e5910ce4752ac0c7438cc [CDFS_NEW] Sync with MS-PL driver 0.4.8-dev-164-g ec6b3ecbe48ad51c366563196cc93a6ae74e8b69 [FILESYSTEMS] switch from CDFS to CDFS_NEW in CMakeLists.txt 0.4.8-dev-160-g 2b217e4ecf942126c4672f8d1c0a2fb55530d731 [NTOSKRNL] Mute spam CcSetReadAheadGranularity() 0.4.8-dev-159-g 64cb138a673fa02d76922963c680bfeb05f1d715 [NTOSKRNL] Mute spam CcPurgeCacheSection() 0.4.8-dev-150-g f723d230a0bc4b7b78ca125abecce137bb96bed6 [CDFS_NEW] 0.4.8-dev-133-g faee3753ea79c7e332c7a1b5eb74ca2c6614e23d [CDFS_NEW] CORE-14003 0.4.8-dev-132-g 1d777ffab5458495c04f250cf7ced379f306a7af [NTOSKRNL] iofunc.c CORE-14003 0.4.8-dev-131-g c3d5a3f2bdff97f03b802fe95dce9d0c9375e53e [NTOSKRNL] iofunc.c CORE-14003 0.4.8-dev-130-g 3b64f7f8fbbc64ada4dfdb6bdd1feff4bac10c1d [NTOSKRNL] ob/obref.c & co CORE-14003 0.4.8-dev-129-g 7eefe702949da68e49c4365d466c5373099c3b1f [NTOSKRNL] io/iomgr.c & co CORE-14003 0.4.8-dev-127-g 5f255827d3282b2dea1bc6d5ba77607550742ced [CDFS_NEW] 0.4.8-dev-126-g 1bef48796e4df655c71ddd92a00417dbe9e530ca [NTOSKRNL] just a comment, superseded later 0.4.8-dev-125-g cbf0430b56b600c29c1f615117574afcce1a9027 [CDFS_NEW] 0.4.8-dev-123-g f88fe43abd6a039f25cc08a8dfd65f9a56ef9da7 [NTOSKRNL] io/iomgr/device.c (forbidden DPRINT) 0.4.8-dev-122-g 6c733856258ebfac4b62ffb7733202dddb74a4be [CDFS_NEW] CORE-13184 0.4.8-dev-97-g 94298313c03c791d1ed472125ebf86f4258d2354 [CDFS_NEW] 0.4.8-dev-95-g e88eeb21af4b778f19b10e2d0e9f1c4361d6838d [CDFS_NEW/NTOSKRNL] CcWaitForCurrentLazyWriterActivity() stub return Success 0.4.8-dev-94-g 03d5be6437a1f2e4376ac117421133ebfdde799e [CDFS_NEW] 0.4.8-dev-93-g fa1c60db50d456fe39e315fbbe18bbee78af4105 [CDFS_NEW] 0.4.8-dev-92-g 8b2fd60829eeeb28fcafc0ef2511f7bed04ffd64 [CDFS_NEW] 0.4.8-dev-91-g e4da7ecc50b59b9f8283d84b3707fa69c595a57d [CDFS_NEW] 0.4.8-dev-90-g 7b19676e2b541983f1062ba1c563099284646010 [CDFS_NEW] 0.4.8-dev-89-g 3d4b8783fd0b9b8231a46e7b914447b86255e35b [CDFS_NEW] 0.4.8-dev-88-g 818025ecc8006c19ce6f6139b21294795f51bafd [CDFS_NEW] 0.4.8-dev-87-g 2639dd673636e4848a4fe33b9a4cd142efcc84f8 [CDFS_NEW] 0.4.8-dev-86-g 755bdb5d0b09e1df374f197c59639c0d78b86d6f [CDFS_NEW] 0.4.8-dev-85-g 3cbcb1badee213fdbadaa2db99086d21a8775fe8 [CDFS_NEW] and mute spam in opcode INSTEAD of picking: 0.4.8-dev-165-g 2284a457a36a9ce7e2b28bf38b6456ff0a6de471 [NTOSKRNL] oplock.c Fixup 0.4.8-dev-163-g d3d585395684b96df9782fe0af253f2c3e9cffc4 [NTOSKRNL] oplock.c Implement oplock-support 0.4.12-dev-232-g f488102c863c46763f36c837265a207dc59dadd5 [CDFS] was also left out for now I am aware, that the backport introduces white-space-glitches within CDFS_NEW. I decided to live with them in favor of better sync to master and newer releases.
2022-01-27 21:10:22 +01:00
extern ULONG ObpAccessProtectCloseBit;
/* PRIVATE FUNCTIONS *********************************************************/
BOOLEAN
FASTCALL
ObReferenceObjectSafe(IN PVOID Object)
{
POBJECT_HEADER ObjectHeader;
LONG OldValue, NewValue;
/* Get the object header */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
/* Get the current reference count and fail if it's zero */
OldValue = ObjectHeader->PointerCount;
if (!OldValue) return FALSE;
/* Start reference loop */
do
{
/* Increase the reference count */
NewValue = InterlockedCompareExchange(&ObjectHeader->PointerCount,
OldValue + 1,
OldValue);
if (OldValue == NewValue) return TRUE;
/* Keep looping */
OldValue = NewValue;
} while (OldValue);
/* If we got here, then the reference count is now 0 */
return FALSE;
}
VOID
NTAPI
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
ObpDeferObjectDeletion(IN POBJECT_HEADER Header)
{
PVOID Entry;
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
/* Loop while trying to update the list */
do
{
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
/* Get the current entry */
Entry = ObpReaperList;
/* Link our object to the list */
Header->NextToFree = Entry;
/* Update the list */
} while (InterlockedCompareExchangePointer(&ObpReaperList,
Header,
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
Entry) != Entry);
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
/* Queue the work item if needed */
if (!Entry) ExQueueWorkItem(&ObpReaperWorkItem, CriticalWorkQueue);
}
LONG
FASTCALL
ObReferenceObjectEx(IN PVOID Object,
IN LONG Count)
{
/* Increment the reference count and return the count now */
return InterlockedExchangeAdd(&OBJECT_TO_OBJECT_HEADER(Object)->
PointerCount,
Count) + Count;
}
LONG
FASTCALL
ObDereferenceObjectEx(IN PVOID Object,
IN LONG Count)
{
POBJECT_HEADER Header;
LONG NewCount;
/* Extract the object header */
Header = OBJECT_TO_OBJECT_HEADER(Object);
/* Check whether the object can now be deleted. */
NewCount = InterlockedExchangeAdd(&Header->PointerCount, -Count) - Count;
if (!NewCount) ObpDeferObjectDeletion(Header);
/* Return the current count */
return NewCount;
}
VOID
FASTCALL
ObInitializeFastReference(IN PEX_FAST_REF FastRef,
IN PVOID Object OPTIONAL)
{
/* Check if we were given an object and reference it 7 times */
if (Object) ObReferenceObjectEx(Object, MAX_FAST_REFS);
/* Setup the fast reference */
ExInitializeFastReference(FastRef, Object);
}
PVOID
FASTCALL
ObFastReferenceObjectLocked(IN PEX_FAST_REF FastRef)
{
PVOID Object;
EX_FAST_REF OldValue = *FastRef;
/* Get the object and reference it slowly */
Object = ExGetObjectFastReference(OldValue);
if (Object) ObReferenceObject(Object);
return Object;
}
PVOID
FASTCALL
ObFastReferenceObject(IN PEX_FAST_REF FastRef)
{
EX_FAST_REF OldValue;
ULONG_PTR Count;
PVOID Object;
/* Reference the object and get it pointer */
OldValue = ExAcquireFastReference(FastRef);
Object = ExGetObjectFastReference(OldValue);
/* Check how many references are left */
Count = ExGetCountFastReference(OldValue);
/* Check if the reference count is over 1 */
if (Count > 1) return Object;
/* Check if the reference count has reached 0 */
if (!Count) return NULL;
/* Otherwise, reference the object 7 times */
ObReferenceObjectEx(Object, MAX_FAST_REFS);
/* Now update the reference count */
if (!ExInsertFastReference(FastRef, Object))
{
/* We failed: completely dereference the object */
ObDereferenceObjectEx(Object, MAX_FAST_REFS);
}
/* Return the Object */
return Object;
}
VOID
FASTCALL
ObFastDereferenceObject(IN PEX_FAST_REF FastRef,
IN PVOID Object)
{
/* Release a fast reference. If this failed, use the slow path */
if (!ExReleaseFastReference(FastRef, Object)) ObDereferenceObject(Object);
}
PVOID
FASTCALL
ObFastReplaceObject(IN PEX_FAST_REF FastRef,
PVOID Object)
{
EX_FAST_REF OldValue;
PVOID OldObject;
ULONG Count;
/* Check if we were given an object and reference it 7 times */
if (Object) ObReferenceObjectEx(Object, MAX_FAST_REFS);
/* Do the swap */
OldValue = ExSwapFastReference(FastRef, Object);
OldObject = ExGetObjectFastReference(OldValue);
/* Check if we had an active object and dereference it */
Count = ExGetCountFastReference(OldValue);
if ((OldObject) && (Count)) ObDereferenceObjectEx(OldObject, Count);
/* Return the old object */
return OldObject;
}
[0.4.7][CDFS_NEW/NTOSKRNL/NDK] Switch from our old CDFS to MS-PL CDFS_NEW The main motivation to switch to that newer driver is, that our old one simply can not read all isos. Especially complex ones made trouble and were only shown as empty in explorer. It is still possible to build and use the old driver when needed, only thing that needs to be done for that is to revert 0.4.8-dev-164-g ec6b3ecbe48ad51c366563196cc93a6ae74e8b69 Porting back the state up to 0.4.8-release-100-g8f947b5 implies: Fixing the following JIRA-IDs (or avoid introducing them): CORE-18029 "Mute noisy DPRINT 'SectionObject has ImageSection'" CORE-17405 "Fix a macro-copy-paste and shrink the binary size" CORE-15659 "Unable to build the gcc Release version in Windows using RosBE 2.1.6 (module cdfs fails)" CORE-14315 "CDFS_NEW assertion during first stage setup due to new CcPerformReadAhead" CORE-14128 "Avast! Free Antivirus 7.0 hangs the system when trying to detect a newly created virus" CORE-14067 "CDFS_NEW assertions and exceptions" CORE-14003 "Shutting down LiveCD asserts since introduction of MS PL CDFS_NEW" CORE-13184 "Restore ability to install from disk-image" by picking the following commits: 0.4.8-release-100-g 8f947b532221069d2f398e25a9c0775c34e21878 [NTOSKRNL] Mute noisy DPRINT 'SectionObject has ImageSection' CORE-18029 0.4.8-release-80-g eb1ea195888e17d026428dc6f406a1834c8702d8 [CDFS_NEW] == 0.4.15-dev-1456-g 889eab7 CORE-17405 0.4.8-release-62-g 8c07aad4a8c6469c7e4ba4c5e92e356a6548189a [CDFS_NEW/XDK] == 0.4.11-dev-39-g a2f9762 + 0.4.11-dev-40-g 6d7ec8c CORE-14067 0.4.8-release-3-g 5d976d04e876aac6990a8f997669711eca83227a [CDFS_NEW] == 0.4.12-dev-431-g bccad87f3ccf266be2179d1322e7a422aeb2f3b7 + 0.4.12-dev-432-g 3463b2db9fc08e5ebe2f5b146d3fe12248f632f3 CORE-15659 0.4.8-RC-3-g 51f9494d484bbe8232e375c2693851316d9d530f [CDFS_NEW] superseded later by the proper fix 0.4.8-release-62-g 8c07aad4a8c6469c7e4ba4c5e92e356a6548189a CORE-14067 0.4.8-dev-1069-g a5e89014dc943b2cbddb16fc4d92e13b7e5068e1 [CDFS_NEW] CORE-14315 0.4.8-dev-475-g a59d4674dec116a951392bb6d136bd11f0e143f2 [NTOSKRNL] io/iomgr/device.c (forgotten assert) CORE-14128 0.4.8-dev-221-g 9d67a24799e29e832933311a8e6ba21787e40f6a [CDFS_NEW] 0.4.8-dev-220-g 67a7e45e351b70356fee442c31cb5de14a0de37e [CDFS_NEW/DOC] 0.4.8-dev-219-g 6a3bbf24e012e4985b97ca4d79604c28fe0133d7 [CDFS_NEW] 0.4.8-dev-218-g ec26cde4a13b3889883d3e1b19f7878179c76df5 [CDFS_NEW] 0.4.8-dev-217-g bc2378a3560a384c47d2a4c83886531ad8f0af90 [CDFS_NEW] 0.4.8-dev-216-g 5429771b9936a6d8aee6ffb3860310673f467e93 [CDFS_NEW] 0.4.8-dev-215-g fd345482634d8ef4c64e5910ce4752ac0c7438cc [CDFS_NEW] Sync with MS-PL driver 0.4.8-dev-164-g ec6b3ecbe48ad51c366563196cc93a6ae74e8b69 [FILESYSTEMS] switch from CDFS to CDFS_NEW in CMakeLists.txt 0.4.8-dev-160-g 2b217e4ecf942126c4672f8d1c0a2fb55530d731 [NTOSKRNL] Mute spam CcSetReadAheadGranularity() 0.4.8-dev-159-g 64cb138a673fa02d76922963c680bfeb05f1d715 [NTOSKRNL] Mute spam CcPurgeCacheSection() 0.4.8-dev-150-g f723d230a0bc4b7b78ca125abecce137bb96bed6 [CDFS_NEW] 0.4.8-dev-133-g faee3753ea79c7e332c7a1b5eb74ca2c6614e23d [CDFS_NEW] CORE-14003 0.4.8-dev-132-g 1d777ffab5458495c04f250cf7ced379f306a7af [NTOSKRNL] iofunc.c CORE-14003 0.4.8-dev-131-g c3d5a3f2bdff97f03b802fe95dce9d0c9375e53e [NTOSKRNL] iofunc.c CORE-14003 0.4.8-dev-130-g 3b64f7f8fbbc64ada4dfdb6bdd1feff4bac10c1d [NTOSKRNL] ob/obref.c & co CORE-14003 0.4.8-dev-129-g 7eefe702949da68e49c4365d466c5373099c3b1f [NTOSKRNL] io/iomgr.c & co CORE-14003 0.4.8-dev-127-g 5f255827d3282b2dea1bc6d5ba77607550742ced [CDFS_NEW] 0.4.8-dev-126-g 1bef48796e4df655c71ddd92a00417dbe9e530ca [NTOSKRNL] just a comment, superseded later 0.4.8-dev-125-g cbf0430b56b600c29c1f615117574afcce1a9027 [CDFS_NEW] 0.4.8-dev-123-g f88fe43abd6a039f25cc08a8dfd65f9a56ef9da7 [NTOSKRNL] io/iomgr/device.c (forbidden DPRINT) 0.4.8-dev-122-g 6c733856258ebfac4b62ffb7733202dddb74a4be [CDFS_NEW] CORE-13184 0.4.8-dev-97-g 94298313c03c791d1ed472125ebf86f4258d2354 [CDFS_NEW] 0.4.8-dev-95-g e88eeb21af4b778f19b10e2d0e9f1c4361d6838d [CDFS_NEW/NTOSKRNL] CcWaitForCurrentLazyWriterActivity() stub return Success 0.4.8-dev-94-g 03d5be6437a1f2e4376ac117421133ebfdde799e [CDFS_NEW] 0.4.8-dev-93-g fa1c60db50d456fe39e315fbbe18bbee78af4105 [CDFS_NEW] 0.4.8-dev-92-g 8b2fd60829eeeb28fcafc0ef2511f7bed04ffd64 [CDFS_NEW] 0.4.8-dev-91-g e4da7ecc50b59b9f8283d84b3707fa69c595a57d [CDFS_NEW] 0.4.8-dev-90-g 7b19676e2b541983f1062ba1c563099284646010 [CDFS_NEW] 0.4.8-dev-89-g 3d4b8783fd0b9b8231a46e7b914447b86255e35b [CDFS_NEW] 0.4.8-dev-88-g 818025ecc8006c19ce6f6139b21294795f51bafd [CDFS_NEW] 0.4.8-dev-87-g 2639dd673636e4848a4fe33b9a4cd142efcc84f8 [CDFS_NEW] 0.4.8-dev-86-g 755bdb5d0b09e1df374f197c59639c0d78b86d6f [CDFS_NEW] 0.4.8-dev-85-g 3cbcb1badee213fdbadaa2db99086d21a8775fe8 [CDFS_NEW] and mute spam in opcode INSTEAD of picking: 0.4.8-dev-165-g 2284a457a36a9ce7e2b28bf38b6456ff0a6de471 [NTOSKRNL] oplock.c Fixup 0.4.8-dev-163-g d3d585395684b96df9782fe0af253f2c3e9cffc4 [NTOSKRNL] oplock.c Implement oplock-support 0.4.12-dev-232-g f488102c863c46763f36c837265a207dc59dadd5 [CDFS] was also left out for now I am aware, that the backport introduces white-space-glitches within CDFS_NEW. I decided to live with them in favor of better sync to master and newer releases.
2022-01-27 21:10:22 +01:00
NTSTATUS
NTAPI
ObReferenceFileObjectForWrite(IN HANDLE Handle,
IN KPROCESSOR_MODE AccessMode,
OUT PFILE_OBJECT *FileObject,
OUT POBJECT_HANDLE_INFORMATION HandleInformation)
{
NTSTATUS Status;
PHANDLE_TABLE HandleTable;
POBJECT_HEADER ObjectHeader;
PHANDLE_TABLE_ENTRY HandleEntry;
ACCESS_MASK GrantedAccess, DesiredAccess;
/* Assume failure */
*FileObject = NULL;
/* Check if this is a special handle */
if (HandleToLong(Handle) < 0)
{
/* Make sure we have a valid kernel handle */
if (AccessMode != KernelMode || Handle == NtCurrentProcess() || Handle == NtCurrentThread())
{
return STATUS_INVALID_HANDLE;
}
/* Use the kernel handle table and get the actual handle value */
Handle = ObKernelHandleToHandle(Handle);
HandleTable = ObpKernelHandleTable;
}
else
{
/* Otherwise use this process's handle table */
HandleTable = PsGetCurrentProcess()->ObjectTable;
}
ASSERT(HandleTable != NULL);
KeEnterCriticalRegion();
/* Get the handle entry */
HandleEntry = ExMapHandleToPointer(HandleTable, Handle);
if (HandleEntry)
{
/* Get the object header and validate the type*/
ObjectHeader = ObpGetHandleObject(HandleEntry);
/* Get the desired access from the file object */
if (!NT_SUCCESS(IoComputeDesiredAccessFileObject((PFILE_OBJECT)&ObjectHeader->Body,
&DesiredAccess)))
{
Status = STATUS_OBJECT_TYPE_MISMATCH;
}
else
{
/* Extract the granted access from the handle entry */
if (BooleanFlagOn(NtGlobalFlag, FLG_KERNEL_STACK_TRACE_DB))
{
/* FIXME: Translate granted access */
GrantedAccess = HandleEntry->GrantedAccess;
}
else
{
GrantedAccess = HandleEntry->GrantedAccess & ~ObpAccessProtectCloseBit;
}
/* FIXME: Get handle information for audit */
HandleInformation->GrantedAccess = GrantedAccess;
/* FIXME: Get handle attributes */
HandleInformation->HandleAttributes = 0;
/* Do granted and desired access match? */
if (GrantedAccess & DesiredAccess)
{
/* FIXME: Audit access if required */
/* Reference the object directly since we have its header */
InterlockedIncrement(&ObjectHeader->PointerCount);
/* Unlock the handle */
ExUnlockHandleTableEntry(HandleTable, HandleEntry);
KeLeaveCriticalRegion();
*FileObject = (PFILE_OBJECT)&ObjectHeader->Body;
/* Return success */
ASSERT(*FileObject != NULL);
return STATUS_SUCCESS;
}
/* No match, deny write access */
Status = STATUS_ACCESS_DENIED;
ExUnlockHandleTableEntry(HandleTable, HandleEntry);
}
}
else
{
Status = STATUS_INVALID_HANDLE;
}
/* Return failure status */
KeLeaveCriticalRegion();
return Status;
}
/* PUBLIC FUNCTIONS *********************************************************/
LONG_PTR
FASTCALL
ObfReferenceObject(IN PVOID Object)
{
ASSERT(Object);
/* Get the header and increment the reference count */
return InterlockedIncrement(&OBJECT_TO_OBJECT_HEADER(Object)->PointerCount);
}
LONG_PTR
FASTCALL
ObfDereferenceObject(IN PVOID Object)
{
POBJECT_HEADER Header;
LONG_PTR OldCount;
/* Extract the object header */
Header = OBJECT_TO_OBJECT_HEADER(Object);
if (Header->PointerCount < Header->HandleCount)
{
DPRINT1("Misbehaving object: %wZ\n", &Header->Type->Name);
return Header->PointerCount;
}
/* Check whether the object can now be deleted. */
OldCount = InterlockedDecrement(&Header->PointerCount);
if (!OldCount)
{
/* Sanity check */
ASSERT(Header->HandleCount == 0);
/* Check if APCs are still active */
if (!KeAreAllApcsDisabled())
{
/* Remove the object */
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
ObpDeleteObject(Object, FALSE);
}
else
{
/* Add us to the deferred deletion list */
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
ObpDeferObjectDeletion(Header);
}
}
/* Return the old count */
return OldCount;
}
VOID
NTAPI
ObDereferenceObjectDeferDelete(IN PVOID Object)
{
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
POBJECT_HEADER Header = OBJECT_TO_OBJECT_HEADER(Object);
/* Check whether the object can now be deleted. */
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
if (!InterlockedDecrement(&Header->PointerCount))
{
/* Add us to the deferred deletion list */
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
ObpDeferObjectDeletion(Header);
}
}
#undef ObDereferenceObject
VOID
NTAPI
ObDereferenceObject(IN PVOID Object)
{
/* Call the fastcall function */
ObfDereferenceObject(Object);
}
NTSTATUS
NTAPI
ObReferenceObjectByPointer(IN PVOID Object,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_TYPE ObjectType,
IN KPROCESSOR_MODE AccessMode)
{
POBJECT_HEADER Header;
/* Get the header */
Header = OBJECT_TO_OBJECT_HEADER(Object);
/*
* Validate object type if the call is for UserMode.
* NOTE: Unless it's a symbolic link (Caz Yokoyama [MSFT])
*/
if ((Header->Type != ObjectType) && ((AccessMode != KernelMode) ||
(ObjectType == ObSymbolicLinkType)))
{
/* Invalid type */
return STATUS_OBJECT_TYPE_MISMATCH;
}
- Fix ObReferenceObjectByName to do proper name validation checks. - Fix ObReferenceObjectByName to call ObpCheckObjectReference before allowing the caller to obtain the reference. - Rename ObFindObject to ObpLookupObjectName and shuffle parameters around and add some placeholder code that resets the object pointer of the lookup context. - Modify ObpChargeQuotaForObject to also return if this is a new object. - Modify ObpDecrementHandleCount to detect when objects with a handle database are being used. Also protect close callout with checks. Protect ObpCloseHAndleTableEntry's callouts with checks as well. - Update logic of ObpIncrementHandleCount and ObpIncrementUnnamedHandleCount to handle currently exclusive objects as well as new handles with OBJ_EXCLUSIVE. Also detect objects that require handle databases and protect callouts. - Support CreatorInfo and the TypeList in ObpIncrementHandleCount. Also update the TotalNumberOfHandles in the object type properly. - Fixup object type lock usage in these routines. - Do proper invalid attributes check in ObOpenObjectByName, and also use a buffer from the pool instead of the stack. - Make ObInsertObject detect invalid object insertions and change some parameter names and checks. - Add stub code to validate the access mask in ObInsertObject. Proper initailize some lookup variables before starting lookup. - Add detection for symbolic link inserts which require some handling code later on. - Free the create information at the right moment isntead of too late. - Add some missing Ob functions, flags and types to the NDK. Fix OBJECT_DIRECTORY structure to use EX_PUSH_LOCK for locks, not ERESOURCE. svn path=/trunk/; revision=25372
2007-01-08 08:03:47 +00:00
/* Increment the reference count and return success */
InterlockedIncrement(&Header->PointerCount);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
- Fix ObReferenceObjectByName to do proper name validation checks. - Fix ObReferenceObjectByName to call ObpCheckObjectReference before allowing the caller to obtain the reference. - Rename ObFindObject to ObpLookupObjectName and shuffle parameters around and add some placeholder code that resets the object pointer of the lookup context. - Modify ObpChargeQuotaForObject to also return if this is a new object. - Modify ObpDecrementHandleCount to detect when objects with a handle database are being used. Also protect close callout with checks. Protect ObpCloseHAndleTableEntry's callouts with checks as well. - Update logic of ObpIncrementHandleCount and ObpIncrementUnnamedHandleCount to handle currently exclusive objects as well as new handles with OBJ_EXCLUSIVE. Also detect objects that require handle databases and protect callouts. - Support CreatorInfo and the TypeList in ObpIncrementHandleCount. Also update the TotalNumberOfHandles in the object type properly. - Fixup object type lock usage in these routines. - Do proper invalid attributes check in ObOpenObjectByName, and also use a buffer from the pool instead of the stack. - Make ObInsertObject detect invalid object insertions and change some parameter names and checks. - Add stub code to validate the access mask in ObInsertObject. Proper initailize some lookup variables before starting lookup. - Add detection for symbolic link inserts which require some handling code later on. - Free the create information at the right moment isntead of too late. - Add some missing Ob functions, flags and types to the NDK. Fix OBJECT_DIRECTORY structure to use EX_PUSH_LOCK for locks, not ERESOURCE. svn path=/trunk/; revision=25372
2007-01-08 08:03:47 +00:00
ObReferenceObjectByName(IN PUNICODE_STRING ObjectPath,
IN ULONG Attributes,
IN PACCESS_STATE PassedAccessState,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_TYPE ObjectType,
IN KPROCESSOR_MODE AccessMode,
IN OUT PVOID ParseContext,
OUT PVOID* ObjectPtr)
{
PVOID Object = NULL;
UNICODE_STRING ObjectName;
NTSTATUS Status;
OBP_LOOKUP_CONTEXT Context;
AUX_ACCESS_DATA AuxData;
ACCESS_STATE AccessState;
- Fix ObReferenceObjectByName to do proper name validation checks. - Fix ObReferenceObjectByName to call ObpCheckObjectReference before allowing the caller to obtain the reference. - Rename ObFindObject to ObpLookupObjectName and shuffle parameters around and add some placeholder code that resets the object pointer of the lookup context. - Modify ObpChargeQuotaForObject to also return if this is a new object. - Modify ObpDecrementHandleCount to detect when objects with a handle database are being used. Also protect close callout with checks. Protect ObpCloseHAndleTableEntry's callouts with checks as well. - Update logic of ObpIncrementHandleCount and ObpIncrementUnnamedHandleCount to handle currently exclusive objects as well as new handles with OBJ_EXCLUSIVE. Also detect objects that require handle databases and protect callouts. - Support CreatorInfo and the TypeList in ObpIncrementHandleCount. Also update the TotalNumberOfHandles in the object type properly. - Fixup object type lock usage in these routines. - Do proper invalid attributes check in ObOpenObjectByName, and also use a buffer from the pool instead of the stack. - Make ObInsertObject detect invalid object insertions and change some parameter names and checks. - Add stub code to validate the access mask in ObInsertObject. Proper initailize some lookup variables before starting lookup. - Add detection for symbolic link inserts which require some handling code later on. - Free the create information at the right moment isntead of too late. - Add some missing Ob functions, flags and types to the NDK. Fix OBJECT_DIRECTORY structure to use EX_PUSH_LOCK for locks, not ERESOURCE. svn path=/trunk/; revision=25372
2007-01-08 08:03:47 +00:00
PAGED_CODE();
/* Fail quickly */
if (!ObjectPath) return STATUS_OBJECT_NAME_INVALID;
/* Capture the name */
Status = ObpCaptureObjectName(&ObjectName, ObjectPath, AccessMode, TRUE);
if (!NT_SUCCESS(Status)) return Status;
- Fix ObReferenceObjectByName to do proper name validation checks. - Fix ObReferenceObjectByName to call ObpCheckObjectReference before allowing the caller to obtain the reference. - Rename ObFindObject to ObpLookupObjectName and shuffle parameters around and add some placeholder code that resets the object pointer of the lookup context. - Modify ObpChargeQuotaForObject to also return if this is a new object. - Modify ObpDecrementHandleCount to detect when objects with a handle database are being used. Also protect close callout with checks. Protect ObpCloseHAndleTableEntry's callouts with checks as well. - Update logic of ObpIncrementHandleCount and ObpIncrementUnnamedHandleCount to handle currently exclusive objects as well as new handles with OBJ_EXCLUSIVE. Also detect objects that require handle databases and protect callouts. - Support CreatorInfo and the TypeList in ObpIncrementHandleCount. Also update the TotalNumberOfHandles in the object type properly. - Fixup object type lock usage in these routines. - Do proper invalid attributes check in ObOpenObjectByName, and also use a buffer from the pool instead of the stack. - Make ObInsertObject detect invalid object insertions and change some parameter names and checks. - Add stub code to validate the access mask in ObInsertObject. Proper initailize some lookup variables before starting lookup. - Add detection for symbolic link inserts which require some handling code later on. - Free the create information at the right moment isntead of too late. - Add some missing Ob functions, flags and types to the NDK. Fix OBJECT_DIRECTORY structure to use EX_PUSH_LOCK for locks, not ERESOURCE. svn path=/trunk/; revision=25372
2007-01-08 08:03:47 +00:00
/* We also need a valid name after capture */
if (!ObjectName.Length) return STATUS_OBJECT_NAME_INVALID;
/* Check if we didn't get an access state */
if (!PassedAccessState)
{
/* Use our built-in access state */
PassedAccessState = &AccessState;
Status = SeCreateAccessState(&AccessState,
&AuxData,
DesiredAccess,
&ObjectType->TypeInfo.GenericMapping);
if (!NT_SUCCESS(Status)) goto Quickie;
}
/* Find the object */
*ObjectPtr = NULL;
- Fix ObReferenceObjectByName to do proper name validation checks. - Fix ObReferenceObjectByName to call ObpCheckObjectReference before allowing the caller to obtain the reference. - Rename ObFindObject to ObpLookupObjectName and shuffle parameters around and add some placeholder code that resets the object pointer of the lookup context. - Modify ObpChargeQuotaForObject to also return if this is a new object. - Modify ObpDecrementHandleCount to detect when objects with a handle database are being used. Also protect close callout with checks. Protect ObpCloseHAndleTableEntry's callouts with checks as well. - Update logic of ObpIncrementHandleCount and ObpIncrementUnnamedHandleCount to handle currently exclusive objects as well as new handles with OBJ_EXCLUSIVE. Also detect objects that require handle databases and protect callouts. - Support CreatorInfo and the TypeList in ObpIncrementHandleCount. Also update the TotalNumberOfHandles in the object type properly. - Fixup object type lock usage in these routines. - Do proper invalid attributes check in ObOpenObjectByName, and also use a buffer from the pool instead of the stack. - Make ObInsertObject detect invalid object insertions and change some parameter names and checks. - Add stub code to validate the access mask in ObInsertObject. Proper initailize some lookup variables before starting lookup. - Add detection for symbolic link inserts which require some handling code later on. - Free the create information at the right moment isntead of too late. - Add some missing Ob functions, flags and types to the NDK. Fix OBJECT_DIRECTORY structure to use EX_PUSH_LOCK for locks, not ERESOURCE. svn path=/trunk/; revision=25372
2007-01-08 08:03:47 +00:00
Status = ObpLookupObjectName(NULL,
&ObjectName,
Attributes,
ObjectType,
AccessMode,
ParseContext,
NULL,
NULL,
PassedAccessState,
&Context,
&Object);
/* Cleanup after lookup */
ObpReleaseLookupContext(&Context);
- Fix ObReferenceObjectByName to do proper name validation checks. - Fix ObReferenceObjectByName to call ObpCheckObjectReference before allowing the caller to obtain the reference. - Rename ObFindObject to ObpLookupObjectName and shuffle parameters around and add some placeholder code that resets the object pointer of the lookup context. - Modify ObpChargeQuotaForObject to also return if this is a new object. - Modify ObpDecrementHandleCount to detect when objects with a handle database are being used. Also protect close callout with checks. Protect ObpCloseHAndleTableEntry's callouts with checks as well. - Update logic of ObpIncrementHandleCount and ObpIncrementUnnamedHandleCount to handle currently exclusive objects as well as new handles with OBJ_EXCLUSIVE. Also detect objects that require handle databases and protect callouts. - Support CreatorInfo and the TypeList in ObpIncrementHandleCount. Also update the TotalNumberOfHandles in the object type properly. - Fixup object type lock usage in these routines. - Do proper invalid attributes check in ObOpenObjectByName, and also use a buffer from the pool instead of the stack. - Make ObInsertObject detect invalid object insertions and change some parameter names and checks. - Add stub code to validate the access mask in ObInsertObject. Proper initailize some lookup variables before starting lookup. - Add detection for symbolic link inserts which require some handling code later on. - Free the create information at the right moment isntead of too late. - Add some missing Ob functions, flags and types to the NDK. Fix OBJECT_DIRECTORY structure to use EX_PUSH_LOCK for locks, not ERESOURCE. svn path=/trunk/; revision=25372
2007-01-08 08:03:47 +00:00
/* Check if the lookup succeeded */
if (NT_SUCCESS(Status))
{
- Fix ObReferenceObjectByName to do proper name validation checks. - Fix ObReferenceObjectByName to call ObpCheckObjectReference before allowing the caller to obtain the reference. - Rename ObFindObject to ObpLookupObjectName and shuffle parameters around and add some placeholder code that resets the object pointer of the lookup context. - Modify ObpChargeQuotaForObject to also return if this is a new object. - Modify ObpDecrementHandleCount to detect when objects with a handle database are being used. Also protect close callout with checks. Protect ObpCloseHAndleTableEntry's callouts with checks as well. - Update logic of ObpIncrementHandleCount and ObpIncrementUnnamedHandleCount to handle currently exclusive objects as well as new handles with OBJ_EXCLUSIVE. Also detect objects that require handle databases and protect callouts. - Support CreatorInfo and the TypeList in ObpIncrementHandleCount. Also update the TotalNumberOfHandles in the object type properly. - Fixup object type lock usage in these routines. - Do proper invalid attributes check in ObOpenObjectByName, and also use a buffer from the pool instead of the stack. - Make ObInsertObject detect invalid object insertions and change some parameter names and checks. - Add stub code to validate the access mask in ObInsertObject. Proper initailize some lookup variables before starting lookup. - Add detection for symbolic link inserts which require some handling code later on. - Free the create information at the right moment isntead of too late. - Add some missing Ob functions, flags and types to the NDK. Fix OBJECT_DIRECTORY structure to use EX_PUSH_LOCK for locks, not ERESOURCE. svn path=/trunk/; revision=25372
2007-01-08 08:03:47 +00:00
/* Check if access is allowed */
if (ObpCheckObjectReference(Object,
PassedAccessState,
FALSE,
AccessMode,
&Status))
{
/* Return the object */
*ObjectPtr = Object;
}
}
/* Free the access state */
if (PassedAccessState == &AccessState)
{
SeDeleteAccessState(PassedAccessState);
}
Quickie:
/* Free the captured name if we had one, and return status */
ObpFreeObjectNameBuffer(&ObjectName);
return Status;
}
NTSTATUS
NTAPI
ObReferenceObjectByHandle(IN HANDLE Handle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_TYPE ObjectType,
IN KPROCESSOR_MODE AccessMode,
OUT PVOID* Object,
OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
{
PHANDLE_TABLE_ENTRY HandleEntry;
POBJECT_HEADER ObjectHeader;
ACCESS_MASK GrantedAccess;
ULONG Attributes;
PEPROCESS CurrentProcess;
PVOID HandleTable;
PETHREAD CurrentThread;
NTSTATUS Status;
PAGED_CODE();
/* Assume failure */
*Object = NULL;
/* Check if this is a special handle */
if (HandleToLong(Handle) < 0)
{
/* Check if this is the current process */
if (Handle == NtCurrentProcess())
{
/* Check if this is the right object type */
if ((ObjectType == PsProcessType) || !(ObjectType))
{
/* Get the current process and granted access */
CurrentProcess = PsGetCurrentProcess();
GrantedAccess = CurrentProcess->GrantedAccess;
/* Validate access */
/* ~GrantedAccess = RefusedAccess.*/
/* ~GrantedAccess & DesiredAccess = list of refused bits. */
/* !(~GrantedAccess & DesiredAccess) == TRUE means ALL requested rights are granted */
if ((AccessMode == KernelMode) ||
!(~GrantedAccess & DesiredAccess))
{
/* Check if the caller wanted handle information */
if (HandleInformation)
{
/* Return it */
HandleInformation->HandleAttributes = 0;
HandleInformation->GrantedAccess = GrantedAccess;
}
/* Reference ourselves */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(CurrentProcess);
InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1);
/* Return the pointer */
*Object = CurrentProcess;
ASSERT(*Object != NULL);
Status = STATUS_SUCCESS;
}
else
{
/* Access denied */
Status = STATUS_ACCESS_DENIED;
}
}
else
{
/* The caller used this special handle value with a non-process type */
Status = STATUS_OBJECT_TYPE_MISMATCH;
}
/* Return the status */
return Status;
}
else if (Handle == NtCurrentThread())
{
/* Check if this is the right object type */
if ((ObjectType == PsThreadType) || !(ObjectType))
{
/* Get the current process and granted access */
CurrentThread = PsGetCurrentThread();
GrantedAccess = CurrentThread->GrantedAccess;
/* Validate access */
/* ~GrantedAccess = RefusedAccess.*/
/* ~GrantedAccess & DesiredAccess = list of refused bits. */
/* !(~GrantedAccess & DesiredAccess) == TRUE means ALL requested rights are granted */
if ((AccessMode == KernelMode) ||
!(~GrantedAccess & DesiredAccess))
{
/* Check if the caller wanted handle information */
if (HandleInformation)
{
/* Return it */
HandleInformation->HandleAttributes = 0;
HandleInformation->GrantedAccess = GrantedAccess;
}
/* Reference ourselves */
ObjectHeader = OBJECT_TO_OBJECT_HEADER(CurrentThread);
InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1);
/* Return the pointer */
*Object = CurrentThread;
ASSERT(*Object != NULL);
Status = STATUS_SUCCESS;
}
else
{
/* Access denied */
Status = STATUS_ACCESS_DENIED;
}
}
else
{
/* The caller used this special handle value with a non-process type */
Status = STATUS_OBJECT_TYPE_MISMATCH;
}
/* Return the status */
return Status;
}
else if (AccessMode == KernelMode)
{
/* Use the kernel handle table and get the actual handle value */
Handle = ObKernelHandleToHandle(Handle);
HandleTable = ObpKernelHandleTable;
}
else
{
/* Invalid access, fail */
return STATUS_INVALID_HANDLE;
}
}
else
{
/* Otherwise use this process's handle table */
HandleTable = PsGetCurrentProcess()->ObjectTable;
}
/* Enter a critical region while we touch the handle table */
ASSERT(HandleTable != NULL);
KeEnterCriticalRegion();
/* Get the handle entry */
HandleEntry = ExMapHandleToPointer(HandleTable, Handle);
if (HandleEntry)
{
/* Get the object header and validate the type*/
ObjectHeader = ObpGetHandleObject(HandleEntry);
if (!(ObjectType) || (ObjectType == ObjectHeader->Type))
{
/* Get the granted access and validate it */
GrantedAccess = HandleEntry->GrantedAccess;
/* Validate access */
/* ~GrantedAccess = RefusedAccess.*/
/* ~GrantedAccess & DesiredAccess = list of refused bits. */
/* !(~GrantedAccess & DesiredAccess) == TRUE means ALL requested rights are granted */
if ((AccessMode == KernelMode) ||
!(~GrantedAccess & DesiredAccess))
{
/* Reference the object directly since we have its header */
InterlockedIncrement(&ObjectHeader->PointerCount);
/* Mask out the internal attributes */
Attributes = HandleEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
/* Check if the caller wants handle information */
if (HandleInformation)
{
/* Fill out the information */
HandleInformation->HandleAttributes = Attributes;
HandleInformation->GrantedAccess = GrantedAccess;
}
/* Return the pointer */
*Object = &ObjectHeader->Body;
/* Unlock the handle */
ExUnlockHandleTableEntry(HandleTable, HandleEntry);
KeLeaveCriticalRegion();
/* Return success */
ASSERT(*Object != NULL);
return STATUS_SUCCESS;
}
else
{
/* Requested access failed */
DPRINT("Rights not granted: %x\n", ~GrantedAccess & DesiredAccess);
Status = STATUS_ACCESS_DENIED;
}
}
else
{
/* Invalid object type */
Status = STATUS_OBJECT_TYPE_MISMATCH;
}
/* Unlock the entry */
ExUnlockHandleTableEntry(HandleTable, HandleEntry);
}
else
{
/* Invalid handle */
Status = STATUS_INVALID_HANDLE;
}
/* Return failure status */
KeLeaveCriticalRegion();
*Object = NULL;
return Status;
}
/* EOF */