From 02a650f8d0a73f86732ee79d83c44dd92d508996 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Tue, 19 Mar 2019 11:15:14 -0700 Subject: [PATCH] sys: ea: return STATUS_EA_CORRUPT_ERROR when appropriate --- src/sys/driver.h | 2 ++ src/sys/ea.c | 17 +++++++++++++++++ tst/winfsp-tests/ea-test.c | 4 ++++ 3 files changed, 23 insertions(+) diff --git a/src/sys/driver.h b/src/sys/driver.h index f23169ed..391e1be9 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -1288,6 +1288,7 @@ typedef struct FSP_FILE_NODE ULONG StreamInfoChangeNumber; UINT64 Ea; ULONG EaChangeNumber; + ULONG EaChangeCount; BOOLEAN TruncateOnClose; FILE_LOCK FileLock; #if (NTDDI_VERSION < NTDDI_WIN8) @@ -1327,6 +1328,7 @@ typedef struct UINT64 DirInfo; ULONG DirInfoCacheHint; ULONG EaIndex; + ULONG EaChangeCount; /* stream support */ HANDLE MainFileHandle; PFILE_OBJECT MainFileObject; diff --git a/src/sys/ea.c b/src/sys/ea.c index 92340442..0b5462b4 100644 --- a/src/sys/ea.c +++ b/src/sys/ea.c @@ -285,6 +285,7 @@ static VOID FspFsvolQueryEaCopy( PAGED_CODE(); PFILE_OBJECT FileObject = IrpSp->FileObject; + FSP_FILE_NODE *FileNode = FileObject->FsContext; FSP_FILE_DESC *FileDesc = FileObject->FsContext2; BOOLEAN RestartScan = BooleanFlagOn(IrpSp->Flags, SL_RESTART_SCAN); BOOLEAN IndexSpecified = BooleanFlagOn(IrpSp->Flags, SL_INDEX_SPECIFIED); @@ -293,6 +294,8 @@ static VOID FspFsvolQueryEaCopy( ULONG EaListLength = IrpSp->Parameters.QueryEa.EaListLength; ULONG EaIndex; + ASSERT(FileNode == FileDesc->FileNode); + if (0 != EaList) { FspFsvolQueryEaGetCopy( @@ -305,6 +308,15 @@ static VOID FspFsvolQueryEaCopy( } else { + if (!IndexSpecified && + !RestartScan && + 0 != FileDesc->EaIndex && + FileNode->EaChangeCount != FileDesc->EaChangeCount) + { + IoStatus->Status = STATUS_EA_CORRUPT_ERROR; + IoStatus->Information = 0; + return; + } if (IndexSpecified) EaIndex = IrpSp->Parameters.QueryEa.EaIndex; else if (RestartScan) @@ -319,7 +331,10 @@ static VOID FspFsvolQueryEaCopy( DstBufBgn, DstSize, IoStatus); if (NT_SUCCESS(IoStatus->Status) || STATUS_BUFFER_OVERFLOW == IoStatus->Status) + { FileDesc->EaIndex = EaIndex; + FileDesc->EaChangeCount = FileNode->EaChangeCount; + } } } @@ -576,6 +591,8 @@ NTSTATUS FspFsvolSetEaComplete( FspFileNodeSetEa(FileNode, 0, 0); } + FileNode->EaChangeCount++; + FspFileNodeNotifyChange(FileNode, FILE_NOTIFY_CHANGE_EA, FILE_ACTION_MODIFIED, FALSE); FspIopRequestContext(Request, RequestFileNode) = 0; diff --git a/tst/winfsp-tests/ea-test.c b/tst/winfsp-tests/ea-test.c index 09868e7d..8abff58f 100644 --- a/tst/winfsp-tests/ea-test.c +++ b/tst/winfsp-tests/ea-test.c @@ -645,6 +645,10 @@ static void ea_check_ea2(HANDLE Handle) } Ea; struct ea_check_ea_context Context; + memset(&Context, 0, sizeof Context); + Result = NtQueryEaFile(Handle, &Iosb, &Ea, sizeof Ea, FALSE, 0, 0, 0, FALSE); + ASSERT(STATUS_EA_CORRUPT_ERROR == Result); + memset(&Context, 0, sizeof Context); Result = NtQueryEaFile(Handle, &Iosb, &Ea, sizeof Ea, FALSE, 0, 0, 0, TRUE); ASSERT(STATUS_SUCCESS == Result);