From 6ae9a993753ac6a4dc55a817f1a29411e14037d9 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Fri, 25 Jul 2008 13:42:05 +0000 Subject: [PATCH] Fix several problems with lookasides and temporary captures: ob_x.h: Add a proper define for the size of a lookaside name buffer oblink.c: Use move memory rather than copy in the case that we re-use the name buffer. We probably never reused it before, because MaximumLength was never set properly. See below. oblife.c: Several things ObpCaptureObjectName - Properly set MaximumLength rather than copping out and setting it to just string + nul. This was dangerous because later, we'll use MaximumLength to determine whether we allocated the name from the lookaside list or the heap. - Since we use MaximumLength to determine where the allocation came from make sure that MaximumLength never equals the magic value if the string comes from the heap for whatever reason. - Free the string using the right symmetry if we would fault copying. ObpCaptureObjectCreateInformation - We didn't allocate the ObjectCreateInfo, but we might've allocated the security descriptor, so free it if needed, rather than borking some non heap. svn path=/trunk/; revision=34783 --- reactos/ntoskrnl/include/internal/ob_x.h | 2 ++ reactos/ntoskrnl/ob/oblife.c | 26 +++++++++++++++++------- reactos/ntoskrnl/ob/oblink.c | 2 +- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ob_x.h b/reactos/ntoskrnl/include/internal/ob_x.h index 91c385e4be0..91877a4c661 100644 --- a/reactos/ntoskrnl/include/internal/ob_x.h +++ b/reactos/ntoskrnl/include/internal/ob_x.h @@ -15,6 +15,8 @@ #define OBP_LOCK_STATE_RELEASED 0xEEEE1234 #define OBP_LOCK_STATE_INITIALIZED 0xFFFF1234 +#define OBP_NAME_LOOKASIDE_MAX_SIZE 248 + ULONG FORCEINLINE ObpSelectObjectLockSlot(IN POBJECT_HEADER ObjectHeader) diff --git a/reactos/ntoskrnl/ob/oblife.c b/reactos/ntoskrnl/ob/oblife.c index 887a3fdccf9..40c5b494352 100644 --- a/reactos/ntoskrnl/ob/oblife.c +++ b/reactos/ntoskrnl/ob/oblife.c @@ -300,9 +300,18 @@ ObpAllocateObjectNameBuffer(IN ULONG Length, MaximumLength = Length + sizeof(UNICODE_NULL); /* Check if we should use the lookaside buffer */ - if (!(UseLookaside) || (MaximumLength > 248)) + if (!(UseLookaside) || (MaximumLength > OBP_NAME_LOOKASIDE_MAX_SIZE)) { /* Nope, allocate directly from pool */ + /* Since we later use MaximumLength to detect that we're not allocating + * from a list, we need at least MaximumLength + sizeof(UNICODE_NULL) + * here. + * + * People do call this with UseLookasideList FALSE so the distinction + * is critical. + */ + if (MaximumLength <= OBP_NAME_LOOKASIDE_MAX_SIZE) + MaximumLength = OBP_NAME_LOOKASIDE_MAX_SIZE + sizeof(UNICODE_NULL); Buffer = ExAllocatePoolWithTag(PagedPool, MaximumLength, OB_NAME_TAG); @@ -310,13 +319,13 @@ ObpAllocateObjectNameBuffer(IN ULONG Length, else { /* Allocate from the lookaside */ - //MaximumLength = 248; <= hack, we should actually set this...! + MaximumLength = OBP_NAME_LOOKASIDE_MAX_SIZE; Buffer = ObpAllocateObjectCreateInfoBuffer(LookasideNameBufferList); } /* Setup the string */ - ObjectName->Length = (USHORT)Length; ObjectName->MaximumLength = (USHORT)MaximumLength; + ObjectName->Length = (USHORT)Length; ObjectName->Buffer = Buffer; return Buffer; } @@ -328,7 +337,7 @@ ObpFreeObjectNameBuffer(IN PUNICODE_STRING Name) PVOID Buffer = Name->Buffer; /* We know this is a pool-allocation if the size doesn't match */ - if (Name->MaximumLength != 248) + if (Name->MaximumLength != OBP_NAME_LOOKASIDE_MAX_SIZE) { /* Free it from the pool */ ExFreePool(Buffer); @@ -408,7 +417,7 @@ ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName, { /* Handle exception and free the string buffer */ Status = _SEH_GetExceptionCode(); - if (StringBuffer) ExFreePool(StringBuffer); + if (StringBuffer) ObpFreeObjectNameBuffer(CapturedName); } _SEH_END; @@ -477,7 +486,7 @@ ObpCaptureObjectCreateInformation(IN POBJECT_ATTRIBUTES ObjectAttributes, if(!NT_SUCCESS(Status)) { /* Capture failed, quit */ - ObjectCreateInfo->SecurityDescriptor = NULL; + ObjectCreateInfo->SecurityDescriptor = NULL; _SEH_LEAVE; } @@ -541,7 +550,10 @@ ObpCaptureObjectCreateInformation(IN POBJECT_ATTRIBUTES ObjectAttributes, } /* Cleanup if we failed */ - if (!NT_SUCCESS(Status)) ObpFreeObjectCreateInformation(ObjectCreateInfo); + if (!NT_SUCCESS(Status)) + { + ObpReleaseObjectCreateInformation(ObjectCreateInfo); + } /* Return status to caller */ return Status; diff --git a/reactos/ntoskrnl/ob/oblink.c b/reactos/ntoskrnl/ob/oblink.c index 71726af4da5..c173d1baf8a 100644 --- a/reactos/ntoskrnl/ob/oblink.c +++ b/reactos/ntoskrnl/ob/oblink.c @@ -181,7 +181,7 @@ ObpParseSymbolicLink(IN PVOID ParsedObject, if (RemainingName->Length) { /* Copy the new path */ - RtlCopyMemory((PVOID)((ULONG_PTR)NewTargetPath + TargetPath->Length), + RtlMoveMemory((PVOID)((ULONG_PTR)NewTargetPath + TargetPath->Length), RemainingName->Buffer, RemainingName->Length); }