- 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:
Alex Ionescu 2007-01-10 01:00:46 +00:00
parent 8fb22da8e5
commit 6e3ccb6ffd
8 changed files with 41 additions and 94 deletions

View file

@ -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;
}
}

View file

@ -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)

View file

@ -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 */

View file

@ -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);

View file

@ -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();

View file

@ -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;
}

View file

@ -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 */

View file

@ -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))