From 2d0c8e14be01c38ae0c5a2f67144a4b40b6823d4 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Wed, 20 Mar 2019 19:06:24 -0700 Subject: [PATCH] sys: FspEaBufferFromOriginatingProcessValidate, FspEaBufferFromFileSystemValidate --- src/sys/create.c | 3 ++- src/sys/driver.h | 6 +++++- src/sys/ea.c | 13 ++++++++----- src/sys/util.c | 33 ++++++++++++++++++++++++++++++--- 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/sys/create.c b/src/sys/create.c index 372bfdeb..1a915105 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -314,7 +314,8 @@ static NTSTATUS FspFsvolCreateNoLock( return STATUS_ACCESS_DENIED; /* is the EA buffer valid? */ - Result = FspEaBufferAndNamesValid(EaBuffer, EaLength, (PULONG)&Irp->IoStatus.Information); + Result = FspEaBufferFromOriginatingProcessValidate( + EaBuffer, EaLength, (PULONG)&Irp->IoStatus.Information); if (!NT_SUCCESS(Result)) return Result; } diff --git a/src/sys/driver.h b/src/sys/driver.h index 391e1be9..b69bc577 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -515,7 +515,11 @@ NTSTATUS FspCcFlushCache(PSECTION_OBJECT_POINTERS SectionObjectPointer, NTSTATUS FspQuerySecurityDescriptorInfo(SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor, PULONG PLength, PSECURITY_DESCRIPTOR ObjectsSecurityDescriptor); -NTSTATUS FspEaBufferAndNamesValid( +NTSTATUS FspEaBufferFromOriginatingProcessValidate( + PFILE_FULL_EA_INFORMATION Buffer, + ULONG Length, + PULONG PErrorOffset); +NTSTATUS FspEaBufferFromFileSystemValidate( PFILE_FULL_EA_INFORMATION Buffer, ULONG Length, PULONG PErrorOffset); diff --git a/src/sys/ea.c b/src/sys/ea.c index c0a3cb3a..4bbd740a 100644 --- a/src/sys/ea.c +++ b/src/sys/ea.c @@ -440,8 +440,9 @@ NTSTATUS FspFsvolQueryEaComplete( Result = STATUS_EA_LIST_INCONSISTENT; FSP_RETURN(); } - Irp->IoStatus.Information = 0; - Result = IoCheckEaBufferValidity((PVOID)Response->Buffer, Response->Rsp.QueryEa.Ea.Size, + Result = FspEaBufferFromFileSystemValidate( + (PVOID)Response->Buffer, /* FspEaBufferFromFileSystemValidate may alter the buffer! */ + Response->Rsp.QueryEa.Ea.Size, (PULONG)&Irp->IoStatus.Information); if (!NT_SUCCESS(Result)) FSP_RETURN(); @@ -534,7 +535,8 @@ static NTSTATUS FspFsvolSetEa( return Result; Buffer = Irp->AssociatedIrp.SystemBuffer; - Result = FspEaBufferAndNamesValid(Buffer, Length, (PULONG)&Irp->IoStatus.Information); + Result = FspEaBufferFromOriginatingProcessValidate( + Buffer, Length, (PULONG)&Irp->IoStatus.Information); if (!NT_SUCCESS(Result)) return Result; @@ -583,8 +585,9 @@ NTSTATUS FspFsvolSetEaComplete( Response->Buffer + Response->Rsp.SetEa.Ea.Size <= (PUINT8)Response + Response->Size) { - Irp->IoStatus.Information = 0; - Result = IoCheckEaBufferValidity((PVOID)Response->Buffer, Response->Rsp.QueryEa.Ea.Size, + Result = FspEaBufferFromFileSystemValidate( + (PVOID)Response->Buffer, /* FspEaBufferFromFileSystemValidate may alter the buffer! */ + Response->Rsp.SetEa.Ea.Size, (PULONG)&Irp->IoStatus.Information); Valid = NT_SUCCESS(Result); } diff --git a/src/sys/util.c b/src/sys/util.c index aabcf5c9..52741ff8 100644 --- a/src/sys/util.c +++ b/src/sys/util.c @@ -49,7 +49,11 @@ NTSTATUS FspCcFlushCache(PSECTION_OBJECT_POINTERS SectionObjectPointer, NTSTATUS FspQuerySecurityDescriptorInfo(SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR SecurityDescriptor, PULONG PLength, PSECURITY_DESCRIPTOR ObjectsSecurityDescriptor); -NTSTATUS FspEaBufferAndNamesValid( +NTSTATUS FspEaBufferFromOriginatingProcessValidate( + PFILE_FULL_EA_INFORMATION Buffer, + ULONG Length, + PULONG PErrorOffset); +NTSTATUS FspEaBufferFromFileSystemValidate( PFILE_FULL_EA_INFORMATION Buffer, ULONG Length, PULONG PErrorOffset); @@ -133,7 +137,8 @@ NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context); #pragma alloc_text(PAGE, FspCcMdlWriteComplete) #pragma alloc_text(PAGE, FspCcFlushCache) #pragma alloc_text(PAGE, FspQuerySecurityDescriptorInfo) -#pragma alloc_text(PAGE, FspEaBufferAndNamesValid) +#pragma alloc_text(PAGE, FspEaBufferFromOriginatingProcessValidate) +#pragma alloc_text(PAGE, FspEaBufferFromFileSystemValidate) #pragma alloc_text(PAGE, FspNotifyInitializeSync) #pragma alloc_text(PAGE, FspNotifyFullChangeDirectory) #pragma alloc_text(PAGE, FspNotifyFullReportChange) @@ -583,7 +588,7 @@ NTSTATUS FspQuerySecurityDescriptorInfo(SECURITY_INFORMATION SecurityInformation return STATUS_BUFFER_TOO_SMALL == Result ? STATUS_BUFFER_OVERFLOW : Result; } -NTSTATUS FspEaBufferAndNamesValid( +NTSTATUS FspEaBufferFromOriginatingProcessValidate( PFILE_FULL_EA_INFORMATION Buffer, ULONG Length, PULONG PErrorOffset) @@ -598,6 +603,7 @@ NTSTATUS FspEaBufferAndNamesValid( if (!NT_SUCCESS(Result)) return Result; + /* check that the EA names are valid */ for (PFILE_FULL_EA_INFORMATION Ea = Buffer, EaEnd = (PVOID)((PUINT8)Ea + Length); EaEnd > Ea; Ea = FSP_NEXT_EA(Ea, EaEnd)) { @@ -616,6 +622,27 @@ NTSTATUS FspEaBufferAndNamesValid( return STATUS_SUCCESS; } +NTSTATUS FspEaBufferFromFileSystemValidate( + PFILE_FULL_EA_INFORMATION Buffer, + ULONG Length, + PULONG PErrorOffset) +{ + PAGED_CODE(); + + PFILE_FULL_EA_INFORMATION LastEa = 0; + + *PErrorOffset = 0; + + /* EA buffers from the user mode file system are allowed to end with NextEntryOffset != 0 */ + for (PFILE_FULL_EA_INFORMATION Ea = Buffer, EaEnd = (PVOID)((PUINT8)Ea + Length); + EaEnd > Ea; Ea = FSP_NEXT_EA(Ea, EaEnd)) + LastEa = Ea; + if (0 != LastEa) + LastEa->NextEntryOffset = 0; + + return IoCheckEaBufferValidity(Buffer, Length, PErrorOffset); +} + NTSTATUS FspNotifyInitializeSync(PNOTIFY_SYNC *NotifySync) { PAGED_CODE();