mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
- Fix a bug in ExfWakePushLock.
- Implement object directory locking to avoid race conditions in Ob and enable most of the query referencing code. svn path=/trunk/; revision=25407
This commit is contained in:
parent
8fb22da8e5
commit
6e3ccb6ffd
8 changed files with 41 additions and 94 deletions
|
@ -97,7 +97,7 @@ ExfWakePushLock(PEX_PUSH_LOCK PushLock,
|
|||
OldValue = NewValue;
|
||||
|
||||
/* Check if it's still locked */
|
||||
if (OldValue.Locked) continue;
|
||||
if (!OldValue.Locked) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ ObpIncrementQueryReference(IN POBJECT_HEADER ObjectHeader,
|
|||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
_ObpDecrementQueryReference(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo)
|
||||
ObpDecrementQueryReference(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo)
|
||||
{
|
||||
POBJECT_DIRECTORY Directory;
|
||||
|
||||
|
@ -79,7 +79,7 @@ _ObpDecrementQueryReference(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo)
|
|||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
_ObpAcquireDirectoryLockShared(IN POBJECT_DIRECTORY Directory,
|
||||
ObpAcquireDirectoryLockShared(IN POBJECT_DIRECTORY Directory,
|
||||
IN POBP_LOOKUP_CONTEXT Context)
|
||||
{
|
||||
/* It's not, set lock flag */
|
||||
|
@ -95,7 +95,7 @@ _ObpAcquireDirectoryLockShared(IN POBJECT_DIRECTORY Directory,
|
|||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
_ObpAcquireDirectoryLockExclusive(IN POBJECT_DIRECTORY Directory,
|
||||
ObpAcquireDirectoryLockExclusive(IN POBJECT_DIRECTORY Directory,
|
||||
IN POBP_LOOKUP_CONTEXT Context)
|
||||
{
|
||||
/* Update lock flag */
|
||||
|
@ -115,7 +115,7 @@ _ObpAcquireDirectoryLockExclusive(IN POBJECT_DIRECTORY Directory,
|
|||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
_ObpReleaseDirectoryLock(IN POBJECT_DIRECTORY Directory,
|
||||
ObpReleaseDirectoryLock(IN POBJECT_DIRECTORY Directory,
|
||||
IN POBP_LOOKUP_CONTEXT Context)
|
||||
{
|
||||
/* Release the lock */
|
||||
|
@ -126,7 +126,7 @@ _ObpReleaseDirectoryLock(IN POBJECT_DIRECTORY Directory,
|
|||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
_ObpInitializeDirectoryLookup(IN POBP_LOOKUP_CONTEXT Context)
|
||||
ObpInitializeDirectoryLookup(IN POBP_LOOKUP_CONTEXT Context)
|
||||
{
|
||||
/* Initialize a null context */
|
||||
Context->Object = NULL;
|
||||
|
@ -137,7 +137,7 @@ _ObpInitializeDirectoryLookup(IN POBP_LOOKUP_CONTEXT Context)
|
|||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
_ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context)
|
||||
ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context)
|
||||
{
|
||||
POBJECT_HEADER ObjectHeader;
|
||||
POBJECT_HEADER_NAME_INFO HeaderNameInfo;
|
||||
|
@ -150,7 +150,7 @@ _ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context)
|
|||
HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
|
||||
|
||||
/* Check if we do have name information */
|
||||
if (HeaderNameInfo) _ObpDecrementQueryReference(HeaderNameInfo);
|
||||
if (HeaderNameInfo) ObpDecrementQueryReference(HeaderNameInfo);
|
||||
|
||||
/* Dereference the object */
|
||||
ObDereferenceObject(Context->Object);
|
||||
|
@ -160,61 +160,21 @@ _ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context)
|
|||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
_ObpCleanupDirectoryLookup(IN POBP_LOOKUP_CONTEXT Context)
|
||||
ObpCleanupDirectoryLookup(IN POBP_LOOKUP_CONTEXT Context)
|
||||
{
|
||||
/* Check if we came back with the directory locked */
|
||||
if (Context->DirectoryLocked)
|
||||
{
|
||||
/* Release the lock */
|
||||
_ObpReleaseDirectoryLock(Context->Directory, Context);
|
||||
ObpReleaseDirectoryLock(Context->Directory, Context);
|
||||
}
|
||||
|
||||
/* Clear the context */
|
||||
Context->Directory = NULL;
|
||||
Context->DirectoryLocked = FALSE;
|
||||
_ObpReleaseLookupContextObject(Context);
|
||||
ObpReleaseLookupContextObject(Context);
|
||||
}
|
||||
|
||||
#if _OB_DEBUG_
|
||||
#define ObpAcquireDirectoryLockShared(a, b) \
|
||||
{ \
|
||||
DbgPrint("OB QUERY: Acquiring lock at %s %d\n", __FUNCTION__, __LINE__);\
|
||||
_ObpAcquireDirectoryLockShared(a, b); \
|
||||
}
|
||||
#define ObpAcquireDirectoryLockExclusive(a, b) \
|
||||
{ \
|
||||
DbgPrint("OB QUERY: Acquiring lock at %s %d\n", __FUNCTION__, __LINE__);\
|
||||
_ObpAcquireDirectoryLockExclusive(a, b); \
|
||||
}
|
||||
#define ObpReleaseDirectoryLock(a, b) \
|
||||
{ \
|
||||
DbgPrint("OB QUERY: Releasing lock at %s %d\n", __FUNCTION__, __LINE__);\
|
||||
_ObpReleaseDirectoryLock(a, b); \
|
||||
}
|
||||
#define ObpInitializeDirectoryLookup(a) \
|
||||
{ \
|
||||
DbgPrint("OB QUERY: Initialization at %s %d\n", __FUNCTION__, __LINE__);\
|
||||
_ObpInitializeDirectoryLookup(a); \
|
||||
}
|
||||
#define ObpCleanupDirectoryLookup(a, b) \
|
||||
{ \
|
||||
DbgPrint("OB QUERY: Cleanup at %s %d\n", __FUNCTION__, __LINE__); \
|
||||
_ObpCleanupDirectoryLookup(a, b); \
|
||||
}
|
||||
#define ObpDecrementQueryReference(a) \
|
||||
{ \
|
||||
DbgPrint("OB QUERY: Decrement at %s %d\n", __FUNCTION__, __LINE__); \
|
||||
_ObpDecrementQueryReference(a); \
|
||||
}
|
||||
#else
|
||||
#define ObpDecrementQueryReference _ObpDecrementQueryReference
|
||||
#define ObpAcquireDirectoryLockExclusive _ObpAcquireDirectoryLockExclusive
|
||||
#define ObpAcquireDirectoryLockShared _ObpAcquireDirectoryLockShared
|
||||
#define ObpReleaseDirectoryLock _ObpReleaseDirectoryLock
|
||||
#define ObpInitializeDirectoryLookup _ObpInitializeDirectoryLookup
|
||||
#define ObpCleanupDirectoryLookup _ObpCleanupDirectoryLookup
|
||||
#endif
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
ObpEnterObjectTypeMutex(IN POBJECT_TYPE ObjectType)
|
||||
|
|
|
@ -247,11 +247,11 @@ ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory,
|
|||
if (HeaderNameInfo)
|
||||
{
|
||||
/* Add a query reference */
|
||||
//ObpIncrementQueryReference(ObjectHeader, HeaderNameInfo);
|
||||
ObpIncrementQueryReference(ObjectHeader, HeaderNameInfo);
|
||||
}
|
||||
|
||||
/* Reference the object being looked up */
|
||||
//ObReferenceObject(FoundObject);
|
||||
ObReferenceObject(FoundObject);
|
||||
|
||||
/* Check if the directory was locked */
|
||||
if (!Context->DirectoryLocked)
|
||||
|
@ -282,7 +282,7 @@ Quickie:
|
|||
if (Context->Object)
|
||||
{
|
||||
/* We already did a lookup, so remove this object's query reference */
|
||||
//ObpRemoveQueryReference(Context->Object);
|
||||
//ObpDecrementQueryReference(Context->Object);
|
||||
}
|
||||
|
||||
/* Return the object we found */
|
||||
|
|
|
@ -1249,7 +1249,7 @@ ObpCreateHandle(IN OB_OPEN_REASON OpenReason,
|
|||
if ((Type) && (ObjectType != Type))
|
||||
{
|
||||
/* They don't, cleanup */
|
||||
//if (Context) ObpCleanupDirectoryLookup(Context);
|
||||
if (Context) ObpCleanupDirectoryLookup(Context);
|
||||
return STATUS_OBJECT_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
|
@ -1287,7 +1287,7 @@ ObpCreateHandle(IN OB_OPEN_REASON OpenReason,
|
|||
* We failed (meaning security failure, according to NT Internals)
|
||||
* detach and return
|
||||
*/
|
||||
//if (Context) ObpCleanupDirectoryLookup(Context);
|
||||
if (Context) ObpCleanupDirectoryLookup(Context);
|
||||
if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
|
||||
return Status;
|
||||
}
|
||||
|
@ -1327,8 +1327,7 @@ ObpCreateHandle(IN OB_OPEN_REASON OpenReason,
|
|||
}
|
||||
|
||||
/* Now we can release the object */
|
||||
//if (Context) ObpCleanupDirectoryLookup(Context);
|
||||
if (Context) Context->Object = NULL;
|
||||
if (Context) ObpCleanupDirectoryLookup(Context);
|
||||
|
||||
/* Save the object header */
|
||||
NewEntry.Object = ObjectHeader;
|
||||
|
@ -2117,8 +2116,7 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Cleanup after lookup */
|
||||
//ObpCleanupDirectoryLookup(&TempBuffer->LookupContext);
|
||||
TempBuffer->LookupContext.Object = NULL;
|
||||
ObpCleanupDirectoryLookup(&TempBuffer->LookupContext);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
|
@ -2152,8 +2150,7 @@ ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
|
|||
Status = STATUS_INVALID_PARAMETER;
|
||||
|
||||
/* Cleanup after lookup */
|
||||
//ObpCleanupDirectoryLookup(&TempBuffer->LookupContext);
|
||||
TempBuffer->LookupContext.Object = NULL;
|
||||
ObpCleanupDirectoryLookup(&TempBuffer->LookupContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2589,6 +2586,9 @@ ObInsertObject(IN PVOID Object,
|
|||
/* Check if anything until now failed */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Cleanup after lookup */
|
||||
ObpCleanupDirectoryLookup(&Context);
|
||||
|
||||
/* Remove query reference that we added */
|
||||
if (ObjectNameInfo) ObpDecrementQueryReference(ObjectNameInfo);
|
||||
|
||||
|
@ -2657,6 +2657,9 @@ ObInsertObject(IN PVOID Object,
|
|||
/* Check if anything until now failed */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Cleanup lookup context */
|
||||
ObpCleanupDirectoryLookup(&Context);
|
||||
|
||||
/* Remove query reference that we added */
|
||||
if (ObjectNameInfo) ObpDecrementQueryReference(ObjectNameInfo);
|
||||
|
||||
|
|
|
@ -282,10 +282,7 @@ ObPostPhase0:
|
|||
ObpInitializeDirectoryLookup(&Context);
|
||||
|
||||
/* Lock it */
|
||||
//ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject, &Context);
|
||||
Context.Directory = ObpTypeDirectoryObject;
|
||||
Context.DirectoryLocked = TRUE;
|
||||
Context.LockStateSignature = 0xCCCC1234;
|
||||
ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject, &Context);
|
||||
|
||||
/* Loop the object types */
|
||||
ListHead = &ObTypeObjectType->TypeList;
|
||||
|
@ -323,8 +320,7 @@ ObPostPhase0:
|
|||
}
|
||||
|
||||
/* Cleanup after lookup */
|
||||
//ObpCleanupDirectoryLookup(&Context);
|
||||
Context.Object = NULL;
|
||||
ObpCleanupDirectoryLookup(&Context);
|
||||
|
||||
/* Initialize DOS Devices Directory and related Symbolic Links */
|
||||
Status = ObpCreateDosDevicesDirectory();
|
||||
|
|
|
@ -965,10 +965,7 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
|
|||
if (ObpTypeDirectoryObject)
|
||||
{
|
||||
/* Acquire the directory lock */
|
||||
//ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject, &Context);
|
||||
Context.Directory = ObpTypeDirectoryObject;
|
||||
Context.DirectoryLocked = TRUE;
|
||||
Context.LockStateSignature = 0xCCCC1234;
|
||||
ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject, &Context);
|
||||
|
||||
/* Do the lookup */
|
||||
if (ObpLookupEntryDirectory(ObpTypeDirectoryObject,
|
||||
|
@ -978,7 +975,7 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
|
|||
&Context))
|
||||
{
|
||||
/* We have already created it, so fail */
|
||||
Context.Object = NULL;
|
||||
ObpCleanupDirectoryLookup(&Context);
|
||||
return STATUS_OBJECT_NAME_COLLISION;
|
||||
}
|
||||
}
|
||||
|
@ -990,7 +987,7 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
|
|||
if (!ObjectName.Buffer)
|
||||
{
|
||||
/* Out of memory, fail */
|
||||
Context.Object = NULL;
|
||||
ObpCleanupDirectoryLookup(&Context);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
|
@ -1007,9 +1004,8 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
|
|||
(POBJECT_HEADER*)&Header);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Context.Object = NULL;
|
||||
|
||||
/* Free the name and fail */
|
||||
ObpCleanupDirectoryLookup(&Context);
|
||||
ExFreePool(ObjectName.Buffer);
|
||||
return Status;
|
||||
}
|
||||
|
@ -1138,7 +1134,8 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
|
|||
ObReferenceObject(ObpTypeDirectoryObject);
|
||||
}
|
||||
|
||||
Context.Object = NULL;
|
||||
/* Cleanup the lookup context */
|
||||
ObpCleanupDirectoryLookup(&Context);
|
||||
|
||||
/* Return the object type and success */
|
||||
*ObjectType = LocalObjectType;
|
||||
|
@ -1146,7 +1143,7 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
|
|||
}
|
||||
|
||||
/* If we got here, then we failed */
|
||||
Context.Object = NULL;
|
||||
ObpCleanupDirectoryLookup(&Context);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
|
|
|
@ -191,16 +191,14 @@ ObpDeleteNameCheck(IN PVOID Object)
|
|||
if (!(ObjectHeader->HandleCount) &&
|
||||
(ObjectNameInfo) &&
|
||||
(ObjectNameInfo->Name.Length) &&
|
||||
(ObjectNameInfo->Directory) &&
|
||||
!(ObjectHeader->Flags & OB_FLAG_PERMANENT))
|
||||
{
|
||||
/* Setup a lookup context */
|
||||
ObpInitializeDirectoryLookup(&Context);
|
||||
|
||||
/* Lock the directory */
|
||||
//ObpAcquireDirectoryLockExclusive(ObjectNameInfo->Directory, &Context);
|
||||
Context.Directory = ObjectNameInfo->Directory;
|
||||
Context.DirectoryLocked = TRUE;
|
||||
Context.LockStateSignature = 0xCCCC1234;
|
||||
ObpAcquireDirectoryLockExclusive(ObjectNameInfo->Directory, &Context);
|
||||
|
||||
/* Do the lookup */
|
||||
Object = ObpLookupEntryDirectory(ObjectNameInfo->Directory,
|
||||
|
@ -253,8 +251,7 @@ ObpDeleteNameCheck(IN PVOID Object)
|
|||
}
|
||||
|
||||
/* Cleanup after lookup */
|
||||
//ObpCleanupDirectoryLookup(&Context);
|
||||
Context.Object = NULL;
|
||||
ObpCleanupDirectoryLookup(&Context);
|
||||
|
||||
/* Remove another query reference since we added one on top */
|
||||
ObpDecrementQueryReference(ObjectNameInfo);
|
||||
|
@ -573,10 +570,7 @@ ReparseNewDir:
|
|||
if (InsertObject)
|
||||
{
|
||||
/* Lock the directory */
|
||||
//ObpAcquireDirectoryLockExclusive(Directory, LookupContext);
|
||||
LookupContext->Directory = Directory;
|
||||
LookupContext->DirectoryLocked = TRUE;
|
||||
LookupContext->LockStateSignature = 0xCCCC1234;
|
||||
ObpAcquireDirectoryLockExclusive(Directory, LookupContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -696,8 +690,7 @@ Reparse:
|
|||
InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1);
|
||||
|
||||
/* Cleanup from the first lookup */
|
||||
//ObpCleanupDirectoryLookup(LookupContext);
|
||||
LookupContext->Object = NULL;
|
||||
ObpCleanupDirectoryLookup(LookupContext);
|
||||
|
||||
/* Check if we have a referenced directory */
|
||||
if (ReferencedDirectory)
|
||||
|
@ -863,8 +856,7 @@ Reparse:
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Cleanup after lookup */
|
||||
//ObpCleanupDirectoryLookup(LookupContext);
|
||||
LookupContext->Object = NULL;
|
||||
ObpCleanupDirectoryLookup(LookupContext);
|
||||
}
|
||||
|
||||
/* Check if we have a device map and dereference it if so */
|
||||
|
|
|
@ -430,8 +430,7 @@ ObReferenceObjectByName(IN PUNICODE_STRING ObjectPath,
|
|||
&Object);
|
||||
|
||||
/* Cleanup after lookup */
|
||||
//ObpCleanupDirectoryLookup(&Context);
|
||||
Context.Object = NULL;
|
||||
ObpCleanupDirectoryLookup(&Context);
|
||||
|
||||
/* Check if the lookup succeeded */
|
||||
if (NT_SUCCESS(Status))
|
||||
|
|
Loading…
Reference in a new issue