From 76af18e4d0be586c4458d1c62ff470860bd4c63d Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Sat, 28 Nov 2015 17:14:11 -0800 Subject: [PATCH] sys: FSP_FSCTL_VOLUME_PARAMS --- inc/winfsp/fsctl.h | 14 +++++++++++--- src/dll/fsctl.c | 12 ++++++++---- src/sys/driver.h | 1 + src/sys/fsctl.c | 20 ++++++++++++-------- 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 4b41969c..957051e8 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -45,8 +45,14 @@ extern const __declspec(selectany) GUID FspFsvrtDeviceClassGuid = #pragma warning(disable:4200) /* zero-sized array in struct/union */ typedef struct { + UINT16 Version; + UINT16 SectorSize; +} FSP_FSCTL_VOLUME_PARAMS; +typedef struct +{ + UINT16 Version; + UINT16 Size; UINT64 Hint; - UINT32 Size; UINT8 Kind; union { @@ -55,8 +61,9 @@ typedef struct } FSP_FSCTL_TRANSACT_REQ; typedef struct { + UINT16 Version; + UINT16 Size; UINT64 Hint; - UINT32 Size; struct { UINT32 Status; @@ -101,7 +108,8 @@ static inline const FSP_FSCTL_TRANSACT_RSP *FspFsctlTransactConsumeResponse( } #if !defined(WINFSP_SYS_INTERNAL) -FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, PSECURITY_DESCRIPTOR SecurityDescriptor, +FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, + const FSP_FSCTL_VOLUME_PARAMS *Params, PSECURITY_DESCRIPTOR SecurityDescriptor, PHANDLE *PVolumeHandle); FSP_API NTSTATUS FspFsctlOpenVolume(PWSTR VolumePath, PHANDLE *PVolumeHandle); diff --git a/src/dll/fsctl.c b/src/dll/fsctl.c index 9237655a..036d29e3 100644 --- a/src/dll/fsctl.c +++ b/src/dll/fsctl.c @@ -16,12 +16,14 @@ static inline VOID GlobalDevicePath(PWCHAR DevicePathBuf, SIZE_T DevicePathSize, L'\\' == DevicePath[0] ? GLOBALROOT "%S" : GLOBALROOT "\\Device\\%S", DevicePath); } -FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, PSECURITY_DESCRIPTOR SecurityDescriptor, +FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, + const FSP_FSCTL_VOLUME_PARAMS *Params, PSECURITY_DESCRIPTOR SecurityDescriptor, PHANDLE *PVolumeHandle) { NTSTATUS Result = STATUS_SUCCESS; WCHAR DevicePathBuf[(sizeof GLOBALROOT + FSP_FSCTL_CREATE_BUFFER_SIZE) / sizeof(WCHAR)]; WCHAR VolumePathBuf[FSP_FSCTL_CREATE_BUFFER_SIZE / sizeof(WCHAR)]; + FSP_FSCTL_VOLUME_PARAMS *ParamsBuf; PSECURITY_DESCRIPTOR SecurityDescriptorBuf = 0; DWORD SecurityDescriptorSize, Bytes; HANDLE DeviceHandle = INVALID_HANDLE_VALUE; @@ -33,17 +35,19 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, PSECURITY_DESCRIPTOR Sec SecurityDescriptorSize = 0; if (!MakeSelfRelativeSD(SecurityDescriptor, 0, &SecurityDescriptorSize)) { - SecurityDescriptorBuf = malloc(SecurityDescriptorSize); - if (0 == SecurityDescriptorBuf) + ParamsBuf = malloc(sizeof *ParamsBuf + SecurityDescriptorSize); + if (0 == ParamsBuf) { Result = STATUS_INSUFFICIENT_RESOURCES; goto exit; } + SecurityDescriptorBuf = (PVOID)(ParamsBuf + 1); if (!MakeSelfRelativeSD(SecurityDescriptor, SecurityDescriptorBuf, &SecurityDescriptorSize)) { Result = FspNtStatusFromWin32(GetLastError()); goto exit; } + *ParamsBuf = *Params; } DeviceHandle = CreateFileW(DevicePathBuf, @@ -55,7 +59,7 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath, PSECURITY_DESCRIPTOR Sec } if (!DeviceIoControl(DeviceHandle, FSP_FSCTL_CREATE, - SecurityDescriptorBuf, SecurityDescriptorSize, VolumePathBuf, sizeof VolumePathBuf, + ParamsBuf, sizeof *ParamsBuf + SecurityDescriptorSize, VolumePathBuf, sizeof VolumePathBuf, &Bytes, 0)) { Result = FspNtStatusFromWin32(GetLastError()); diff --git a/src/sys/driver.h b/src/sys/driver.h index e6f20591..28e35b4e 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -253,6 +253,7 @@ typedef struct typedef struct { FSP_DEVICE_EXTENSION Base; + FSP_FSCTL_VOLUME_PARAMS VolumeParams; FSP_IOQ Ioq; UINT8 SecurityDescriptorBuf[]; } FSP_FSVRT_DEVICE_EXTENSION; diff --git a/src/sys/fsctl.c b/src/sys/fsctl.c index c38046ac..11696f40 100644 --- a/src/sys/fsctl.c +++ b/src/sys/fsctl.c @@ -44,8 +44,11 @@ static NTSTATUS FspFsctlCreateVolume( ULONG InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength; ULONG OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength; PVOID SystemBuffer = Irp->AssociatedIrp.SystemBuffer; - if (0 == InputBufferLength || 0 == SystemBuffer || - !RtlValidRelativeSecurityDescriptor(SystemBuffer, InputBufferLength, + const FSP_FSCTL_VOLUME_PARAMS *Params = SystemBuffer; + PSECURITY_DESCRIPTOR SecurityDescriptor = (PVOID)(Params + 1); + DWORD SecurityDescriptorSize = InputBufferLength - sizeof *Params; + if (sizeof *Params >= InputBufferLength || 0 == SystemBuffer || + !RtlValidRelativeSecurityDescriptor(SecurityDescriptor, SecurityDescriptorSize, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION)) return STATUS_INVALID_PARAMETER; if (FSP_FSCTL_CREATE_BUFFER_SIZE > OutputBufferLength) @@ -60,10 +63,10 @@ static NTSTATUS FspFsctlCreateVolume( return Result; /* copy the security descriptor from the system buffer to a temporary one */ - PVOID SecurityDescriptor = ExAllocatePoolWithTag(PagedPool, InputBufferLength, FSP_TAG); - if (0 == SecurityDescriptor) + PVOID SecurityDescriptorBuf = ExAllocatePoolWithTag(PagedPool, SecurityDescriptorSize, FSP_TAG); + if (0 == SecurityDescriptorBuf) return STATUS_INSUFFICIENT_RESOURCES; - RtlCopyMemory(SecurityDescriptor, SystemBuffer, InputBufferLength); + RtlCopyMemory(SecurityDescriptorBuf, SecurityDescriptor, SecurityDescriptorSize); /* create the virtual volume device */ PDEVICE_OBJECT FsvrtDeviceObject; @@ -78,7 +81,7 @@ static NTSTATUS FspFsctlCreateVolume( Guid.Data4[4], Guid.Data4[5], Guid.Data4[6], Guid.Data4[7]); ASSERT(NT_SUCCESS(Result)); Result = IoCreateDeviceSecure(DeviceObject->DriverObject, - sizeof(FSP_FSVRT_DEVICE_EXTENSION) + InputBufferLength, &DeviceName, FILE_DEVICE_VIRTUAL_DISK, + sizeof(FSP_FSVRT_DEVICE_EXTENSION) + SecurityDescriptorSize, &DeviceName, FILE_DEVICE_VIRTUAL_DISK, FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceSddl, 0, &FsvrtDeviceObject); @@ -86,14 +89,15 @@ static NTSTATUS FspFsctlCreateVolume( { FSP_FSVRT_DEVICE_EXTENSION *FsvrtDeviceExtension = FspFsvrtDeviceExtension(FsvrtDeviceObject); FsvrtDeviceExtension->Base.Kind = FspFsvrtDeviceExtensionKind; + FsvrtDeviceExtension->VolumeParams = *Params; FspIoqInitialize(&FsvrtDeviceExtension->Ioq); RtlCopyMemory(FspFsvrtDeviceExtension(FsvrtDeviceObject)->SecurityDescriptorBuf, - SecurityDescriptor, InputBufferLength); + SecurityDescriptorBuf, SecurityDescriptorSize); Irp->IoStatus.Information = DeviceName.Length + 1; } /* free the temporary security descriptor */ - ExFreePoolWithTag(SecurityDescriptor, FSP_TAG); + ExFreePoolWithTag(SecurityDescriptorBuf, FSP_TAG); return Result; }