From be8c29114a213e6ab62379f8392fc50dd84f31a3 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Mon, 12 Sep 2016 15:11:45 -0700 Subject: [PATCH] sys: FspFsvolFileSystemControlReparsePoint: improve computation of TargetOnFileSystem field when MUP is being used --- src/sys/driver.h | 8 +++++--- src/sys/fsctl.c | 53 +++++++++++++++++++++++++++++++++++++++++++----- src/sys/util.c | 15 ++++++-------- 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/src/sys/driver.h b/src/sys/driver.h index 725e1636..55af8430 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -45,6 +45,7 @@ #define FSP_ALLOC_INTERNAL_TAG 'IpsF' #define FSP_ALLOC_EXTERNAL_TAG 'XpsF' #define FSP_IO_INCREMENT IO_NETWORK_INCREMENT +#define FSP_VOLUME_PREFIX_CASE_INS TRUE /* debug */ #if DBG @@ -427,8 +428,8 @@ PVOID FspAllocateIrpMustSucceed(CCHAR StackSize); BOOLEAN FspUnicodePathIsValid(PUNICODE_STRING Path, BOOLEAN AllowStreams); VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix); NTSTATUS FspCreateGuid(GUID *Guid); -NTSTATUS FspGetDeviceObjectByName(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, - PULONG PFileNameIndex, PDEVICE_OBJECT *PDeviceObject); +NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, + PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject); NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length); NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); @@ -820,7 +821,8 @@ VOID FspFsvolDeviceInvalidateVolumeInfo(PDEVICE_OBJECT DeviceObject); static inline BOOLEAN FspFsvolDeviceVolumePrefixInString(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING String) { - return RtlPrefixUnicodeString(&FspFsvolDeviceExtension(DeviceObject)->VolumePrefix, String, TRUE); + return RtlPrefixUnicodeString(&FspFsvolDeviceExtension(DeviceObject)->VolumePrefix, String, + FSP_VOLUME_PREFIX_CASE_INS); } NTSTATUS FspDeviceCopyList( PDEVICE_OBJECT **PDeviceObjects, PULONG PDeviceObjectCount); diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c index fdebebde..1ac8adaa 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -150,19 +150,62 @@ static NTSTATUS FspFsvolFileSystemControlReparsePoint( { UNICODE_STRING TargetObjectName; PDEVICE_OBJECT TargetDeviceObject; + PFILE_OBJECT TargetFileObject; ULONG TargetFileNameIndex; + ULONG32 TargetProviderId; + FSRTL_MUP_PROVIDER_INFO_LEVEL_1 ProviderInfo; + ULONG ProviderInfoSize; TargetObjectName.Length = TargetObjectName.MaximumLength = ReparseTargetPathLength; TargetObjectName.Buffer = ReparseTargetPath; - Result = FspGetDeviceObjectByName(&TargetObjectName, FILE_READ_DATA, - &TargetFileNameIndex, &TargetDeviceObject); + Result = FspGetDeviceObjectPointer(&TargetObjectName, FILE_READ_DATA, + &TargetFileNameIndex, &TargetFileObject, &TargetDeviceObject); if (!NT_SUCCESS(Result)) goto target_check_exit; - TargetOnFileSystem = IoGetRelatedDeviceObject(FileObject) == TargetDeviceObject ? - (UINT16)TargetFileNameIndex : 0; - ObDereferenceObject(TargetDeviceObject); + if (TargetFileNameIndex < ReparseTargetPathLength && + IoGetRelatedDeviceObject(FileObject) == TargetDeviceObject) + { + if (0 == FsvolDeviceExtension->VolumePrefix.Length) + TargetOnFileSystem = (UINT16)TargetFileNameIndex; + else + { + ProviderInfoSize = sizeof ProviderInfo; + Result = FsRtlMupGetProviderInfoFromFileObject(TargetFileObject, 1, + &ProviderInfo, &ProviderInfoSize); + if (NT_SUCCESS(Result)) + { + TargetProviderId = ProviderInfo.ProviderId; + + ProviderInfoSize = sizeof ProviderInfo; + Result = FsRtlMupGetProviderInfoFromFileObject(FileObject, 1, + &ProviderInfo, &ProviderInfoSize); + if (!NT_SUCCESS(Result)) + goto target_check_exit; + + if (ProviderInfo.ProviderId == TargetProviderId) + TargetOnFileSystem = (UINT16)TargetFileNameIndex; + } + else + { + TargetObjectName.Length = TargetObjectName.MaximumLength = + FsvolDeviceExtension->VolumePrefix.Length; + TargetObjectName.Buffer = ReparseTargetPath + + TargetFileNameIndex / sizeof(WCHAR); + + TargetFileNameIndex += FsvolDeviceExtension->VolumePrefix.Length; + + if (TargetFileNameIndex < ReparseTargetPathLength && + RtlEqualUnicodeString(&FsvolDeviceExtension->VolumePrefix, + &TargetObjectName, + FSP_VOLUME_PREFIX_CASE_INS)) + TargetOnFileSystem = (UINT16)TargetFileNameIndex; + } + } + } + + ObDereferenceObject(TargetFileObject); target_check_exit: ; diff --git a/src/sys/util.c b/src/sys/util.c index baf95f08..1989d231 100644 --- a/src/sys/util.c +++ b/src/sys/util.c @@ -20,8 +20,8 @@ BOOLEAN FspUnicodePathIsValid(PUNICODE_STRING Path, BOOLEAN AllowStreams); VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE_STRING Suffix); NTSTATUS FspCreateGuid(GUID *Guid); -NTSTATUS FspGetDeviceObjectByName(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, - PULONG PFileNameIndex, PDEVICE_OBJECT *PDeviceObject); +NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, + PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject); NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length); static NTSTATUS FspSendSetInformationIrpCompletion( @@ -90,7 +90,7 @@ NTSTATUS FspIrpHookNext(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context); #pragma alloc_text(PAGE, FspUnicodePathIsValid) #pragma alloc_text(PAGE, FspUnicodePathSuffix) #pragma alloc_text(PAGE, FspCreateGuid) -#pragma alloc_text(PAGE, FspGetDeviceObjectByName) +#pragma alloc_text(PAGE, FspGetDeviceObjectPointer) #pragma alloc_text(PAGE, FspSendSetInformationIrp) #pragma alloc_text(PAGE, FspBufferUserBuffer) #pragma alloc_text(PAGE, FspLockUserBuffer) @@ -246,13 +246,12 @@ NTSTATUS FspCreateGuid(GUID *Guid) return Result; } -NTSTATUS FspGetDeviceObjectByName(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, - PULONG PFileNameIndex, PDEVICE_OBJECT *PDeviceObject) +NTSTATUS FspGetDeviceObjectPointer(PUNICODE_STRING ObjectName, ACCESS_MASK DesiredAccess, + PULONG PFileNameIndex, PFILE_OBJECT *PFileObject, PDEVICE_OBJECT *PDeviceObject) { PAGED_CODE(); UNICODE_STRING PartialName; - PFILE_OBJECT FileObject; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE Handle; NTSTATUS Result; @@ -271,12 +270,10 @@ NTSTATUS FspGetDeviceObjectByName(PUNICODE_STRING ObjectName, ACCESS_MASK Desire L'\\' != PartialName.Buffer[PartialName.Length / sizeof(WCHAR)]) PartialName.Length += sizeof(WCHAR); - Result = IoGetDeviceObjectPointer(&PartialName, DesiredAccess, &FileObject, PDeviceObject); + Result = IoGetDeviceObjectPointer(&PartialName, DesiredAccess, PFileObject, PDeviceObject); if (NT_SUCCESS(Result)) { *PFileNameIndex = PartialName.Length; - ObReferenceObject(*PDeviceObject); - ObDereferenceObject(FileObject); break; }