diff --git a/src/sys/dirctl.c b/src/sys/dirctl.c index b9bdd56e..2c2059b5 100644 --- a/src/sys/dirctl.c +++ b/src/sys/dirctl.c @@ -74,6 +74,12 @@ enum RequestProcess = 3, }; +enum +{ + FspFsvolQueryDirectoryLengthMax = + FspFsvolDeviceDirInfoCacheItemSizeMax - FspMetaCacheItemHeaderSize, +}; + static NTSTATUS FspFsvolQueryDirectoryCopy( PUNICODE_STRING DirectoryPattern, BOOLEAN CaseInsensitive, PUNICODE_STRING DirectoryMarker, PUNICODE_STRING DirectoryMarkerOut, @@ -544,7 +550,7 @@ static NTSTATUS FspFsvolQueryDirectoryRetry( QueryDirectoryLengthMin = sizeof(FSP_FSCTL_DIR_INFO) + FsvolDeviceExtension->VolumeParams.MaxComponentLength * sizeof(WCHAR); QueryDirectoryLengthMin = FSP_FSCTL_ALIGN_UP(QueryDirectoryLengthMin, 8); - ASSERT(QueryDirectoryLengthMin < FspFsvolDeviceDirInfoCacheItemSizeMax); + ASSERT(QueryDirectoryLengthMin < FspFsvolQueryDirectoryLengthMax); if (0 != FsvolDeviceExtension->VolumeParams.FileInfoTimeout && 0 == FileDesc->DirectoryMarker.Buffer) { @@ -557,11 +563,11 @@ static NTSTATUS FspFsvolQueryDirectoryRetry( QueryDirectoryLength = FSP_FSCTL_ALIGN_UP(QueryDirectoryLength, 8); if (QueryDirectoryLength < QueryDirectoryLengthMin) QueryDirectoryLength = QueryDirectoryLengthMin; - else if (QueryDirectoryLength > FspFsvolDeviceDirInfoCacheItemSizeMax) - QueryDirectoryLength = FspFsvolDeviceDirInfoCacheItemSizeMax; + else if (QueryDirectoryLength > FspFsvolQueryDirectoryLengthMax) + QueryDirectoryLength = FspFsvolQueryDirectoryLengthMax; } else - QueryDirectoryLength = FspFsvolDeviceDirInfoCacheItemSizeMax; + QueryDirectoryLength = FspFsvolQueryDirectoryLengthMax; } else { @@ -575,11 +581,11 @@ static NTSTATUS FspFsvolQueryDirectoryRetry( QueryDirectoryLength = FSP_FSCTL_ALIGN_UP(QueryDirectoryLength, 8); if (QueryDirectoryLength < QueryDirectoryLengthMin) QueryDirectoryLength = QueryDirectoryLengthMin; - else if (QueryDirectoryLength > FspFsvolDeviceDirInfoCacheItemSizeMax) - QueryDirectoryLength = FspFsvolDeviceDirInfoCacheItemSizeMax; + else if (QueryDirectoryLength > FspFsvolQueryDirectoryLengthMax) + QueryDirectoryLength = FspFsvolQueryDirectoryLengthMax; } else - QueryDirectoryLength = FspFsvolDeviceDirInfoCacheItemSizeMax; + QueryDirectoryLength = FspFsvolQueryDirectoryLengthMax; } Request->Kind = FspFsctlTransactQueryDirectoryKind; diff --git a/src/sys/driver.h b/src/sys/driver.h index a5c1c7ff..9cf2c752 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -837,6 +837,10 @@ PIRP FspIoqNextCompleteIrp(FSP_IOQ *Ioq, PIRP BoundaryIrp); ULONG FspIoqRetriedIrpCount(FSP_IOQ *Ioq); /* meta cache */ +enum +{ + FspMetaCacheItemHeaderSize = MEMORY_ALLOCATION_ALIGNMENT, +}; typedef struct { KSPIN_LOCK SpinLock; diff --git a/src/sys/meta.c b/src/sys/meta.c index 6a7d9c7f..e284336f 100644 --- a/src/sys/meta.c +++ b/src/sys/meta.c @@ -33,6 +33,8 @@ typedef struct ULONG Size; __declspec(align(MEMORY_ALLOCATION_ALIGNMENT)) UINT8 Buffer[]; } FSP_META_CACHE_ITEM_BUFFER; +FSP_FSCTL_STATIC_ASSERT(FIELD_OFFSET(FSP_META_CACHE_ITEM_BUFFER, Buffer) == FspMetaCacheItemHeaderSize, + "FspMetaCacheItemHeaderSize must match offset of FSP_META_CACHE_ITEM_BUFFER::Buffer"); static inline VOID FspMetaCacheDereferenceItem(FSP_META_CACHE_ITEM *Item) { @@ -218,7 +220,16 @@ UINT64 FspMetaCacheAddItem(FSP_META_CACHE *MetaCache, PCVOID Buffer, ULONG Size) Item->RefCount = 1; ItemBuffer->Item = Item; ItemBuffer->Size = Size; - RtlCopyMemory(ItemBuffer->Buffer, Buffer, Size); + try + { + RtlCopyMemory(ItemBuffer->Buffer, Buffer, Size); + } + except (EXCEPTION_EXECUTE_HANDLER) + { + FspFree(ItemBuffer); + FspFree(Item); + return 0; + } KeAcquireSpinLock(&MetaCache->SpinLock, &Irql); if (MetaCache->ItemCount >= MetaCache->MetaCapacity) FspMetaCacheRemoveExpiredItemAtDpcLevel(MetaCache, (UINT64)-1LL);