diff --git a/src/sys/driver.h b/src/sys/driver.h index bd4d4e94..737b5a98 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -391,6 +391,7 @@ VOID FspUnicodePathSuffix(PUNICODE_STRING Path, PUNICODE_STRING Remain, PUNICODE NTSTATUS FspCreateGuid(GUID *Guid); 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); NTSTATUS FspLockUserBuffer(PVOID UserBuffer, ULONG Length, KPROCESSOR_MODE RequestorMode, LOCK_OPERATION Operation, PMDL *PMdl); NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress); diff --git a/src/sys/security.c b/src/sys/security.c index 77033448..682fa48d 100644 --- a/src/sys/security.c +++ b/src/sys/security.c @@ -59,6 +59,7 @@ static NTSTATUS FspFsvolQuerySecurity( PVOID Buffer = Irp->UserBuffer; ULONG Length = IrpSp->Parameters.QuerySecurity.Length; PVOID SecurityBuffer; + FSP_FSCTL_TRANSACT_REQ *Request; ASSERT(FileNode == FileDesc->FileNode); @@ -76,7 +77,12 @@ static NTSTATUS FspFsvolQuerySecurity( FspFileNodeAcquireShared(FileNode, Pgio); - FSP_FSCTL_TRANSACT_REQ *Request; + Result = FspBufferUserBuffer(Irp, Length, IoWriteAccess); + if (!NT_SUCCESS(Result)) + { + FspFileNodeRelease(FileNode, Full); + return Result; + } Result = FspIopCreateRequestEx(Irp, 0, 0, FspFsvolQuerySecurityRequestFini, &Request); if (!NT_SUCCESS(Result)) @@ -110,7 +116,7 @@ NTSTATUS FspFsvolQuerySecurityComplete( PFILE_OBJECT FileObject = IrpSp->FileObject; FSP_FILE_NODE *FileNode = FileObject->FsContext; SECURITY_INFORMATION SecurityInformation = IrpSp->Parameters.QuerySecurity.SecurityInformation; - PVOID Buffer = Irp->UserBuffer; + PVOID Buffer = Irp->AssociatedIrp.SystemBuffer; ULONG Length = IrpSp->Parameters.QuerySecurity.Length; PVOID SecurityBuffer = 0; FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); diff --git a/src/sys/util.c b/src/sys/util.c index cd0cdc39..f7fb6892 100644 --- a/src/sys/util.c +++ b/src/sys/util.c @@ -13,6 +13,7 @@ NTSTATUS FspSendSetInformationIrp(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT File FILE_INFORMATION_CLASS FileInformationClass, PVOID FileInformation, ULONG Length); static NTSTATUS FspSendSetInformationIrpCompletion( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context0); +NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation); NTSTATUS FspLockUserBuffer(PVOID UserBuffer, ULONG Length, KPROCESSOR_MODE RequestorMode, LOCK_OPERATION Operation, PMDL *PMdl); NTSTATUS FspMapLockedPagesInUserMode(PMDL Mdl, PVOID *PAddress); @@ -50,6 +51,7 @@ VOID FspSafeMdlDelete(FSP_SAFE_MDL *SafeMdl); #pragma alloc_text(PAGE, FspUnicodePathSuffix) #pragma alloc_text(PAGE, FspCreateGuid) #pragma alloc_text(PAGE, FspSendSetInformationIrp) +#pragma alloc_text(PAGE, FspBufferUserBuffer) #pragma alloc_text(PAGE, FspLockUserBuffer) #pragma alloc_text(PAGE, FspMapLockedPagesInUserMode) #pragma alloc_text(PAGE, FspCcInitializeCacheMap) @@ -250,6 +252,39 @@ static NTSTATUS FspSendSetInformationIrpCompletion( return STATUS_MORE_PROCESSING_REQUIRED; } +NTSTATUS FspBufferUserBuffer(PIRP Irp, ULONG Length, LOCK_OPERATION Operation) +{ + PAGED_CODE(); + + if (0 == Length || 0 != Irp->AssociatedIrp.SystemBuffer) + return STATUS_SUCCESS; + + PVOID SystemBuffer = FspAllocNonPagedExternal(Length); + if (0 == SystemBuffer) + return STATUS_INSUFFICIENT_RESOURCES; + + if (IoReadAccess == Operation) + { + try + { + RtlCopyMemory(SystemBuffer, Irp->UserBuffer, Length); + } + except (EXCEPTION_EXECUTE_HANDLER) + { + FspFree(SystemBuffer); + return STATUS_INVALID_USER_BUFFER; + } + } + else + RtlZeroMemory(SystemBuffer, Length); + + Irp->AssociatedIrp.SystemBuffer = SystemBuffer; + Irp->Flags |= (IoReadAccess == Operation ? 0 : IRP_INPUT_OPERATION) | + IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER; + + return STATUS_SUCCESS; +} + NTSTATUS FspLockUserBuffer(PVOID UserBuffer, ULONG Length, KPROCESSOR_MODE RequestorMode, LOCK_OPERATION Operation, PMDL *PMdl) {