diff --git a/src/sys/callbacks.c b/src/sys/callbacks.c index 15551d8b..af3d94e8 100644 --- a/src/sys/callbacks.c +++ b/src/sys/callbacks.c @@ -78,6 +78,7 @@ VOID FspAcquireFileForNtCreateSection( { /* Callers: * CcWriteBehind + * MmCreateSection and friends */ FSP_ENTER_VOID(PAGED_CODE()); @@ -85,6 +86,8 @@ VOID FspAcquireFileForNtCreateSection( FSP_FILE_NODE *FileNode = FileObject->FsContext; FspFileNodeAcquireExclusive(FileNode, Full); + ASSERT(FALSE == FileNode->Tls.CreateSection); + FileNode->Tls.CreateSection = TRUE; FSP_LEAVE_VOID("FileObject=%p", FileObject); } @@ -94,12 +97,14 @@ VOID FspReleaseFileForNtCreateSection( { /* Callers: * CcWriteBehind + * MmCreateSection and friends */ FSP_ENTER_VOID(PAGED_CODE()); FSP_FILE_NODE *FileNode = FileObject->FsContext; + FileNode->Tls.CreateSection = FALSE; FspFileNodeRelease(FileNode, Full); FSP_LEAVE_VOID("FileObject=%p", FileObject); diff --git a/src/sys/driver.h b/src/sys/driver.h index 1a78518d..f87f1bb9 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -1392,6 +1392,7 @@ typedef struct FSP_FILE_NODE PIRP TopLevelIrp; UINT32 TopFlags; } CcFlush; + BOOLEAN CreateSection; } Tls; /* read-only after creation (and insertion in the ContextTable) */ PDEVICE_OBJECT FsvolDeviceObject; diff --git a/src/sys/read.c b/src/sys/read.c index c2581309..748e9185 100644 --- a/src/sys/read.c +++ b/src/sys/read.c @@ -234,6 +234,7 @@ static NTSTATUS FspFsvolReadNonCached( ULONG ReadLength = IrpSp->Parameters.Read.Length; ULONG ReadKey = IrpSp->Parameters.Read.Key; BOOLEAN PagingIo = BooleanFlagOn(Irp->Flags, IRP_PAGING_IO); + FSP_FSCTL_FILE_INFO FileInfo; FSP_FSCTL_TRANSACT_REQ *Request; BOOLEAN Success; @@ -296,6 +297,19 @@ static NTSTATUS FspFsvolReadNonCached( } } + /* trim ReadLength during CreateProcess; resolve bugcheck for filesystem that reports incorrect size */ + if (FileNode->Tls.CreateSection) + { + FspFileNodeGetFileInfo(FileNode, &FileInfo); + if ((UINT64)ReadOffset.QuadPart >= FileInfo.FileSize) + { + FspFileNodeRelease(FileNode, Full); + return STATUS_END_OF_FILE; + } + if ((UINT64)ReadLength > FileInfo.FileSize - ReadOffset.QuadPart) + ReadLength = (ULONG)(FileInfo.FileSize - ReadOffset.QuadPart); + } + /* convert FileNode to shared */ FspFileNodeConvertExclusiveToShared(FileNode, Full);