From 0605f7832f5d0d4c5f1624f2fc6b4fcdf41a4676 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Tue, 18 Oct 2011 18:02:56 +0000 Subject: [PATCH] [KS] - Probe input / output parameters when requests are coming from user mode - Fix KspPinPropertyHandler to use the correct output parameter location - Fix KsHandleSizedListQuery to use the correct output parameter location - Tested in Vbox 4.1.4 r74291 - May fix a few sound drivers who are having user mode extra utility apps svn path=/trunk/; revision=54191 --- reactos/drivers/ksfilter/ks/connectivity.c | 4 +- reactos/drivers/ksfilter/ks/property.c | 109 +++++++++++++++++++-- 2 files changed, 103 insertions(+), 10 deletions(-) diff --git a/reactos/drivers/ksfilter/ks/connectivity.c b/reactos/drivers/ksfilter/ks/connectivity.c index 2825221c4d1..7cd0fabb740 100644 --- a/reactos/drivers/ksfilter/ks/connectivity.c +++ b/reactos/drivers/ksfilter/ks/connectivity.c @@ -333,7 +333,7 @@ KspPinPropertyHandler( LPGUID Guid; IoStack = IoGetCurrentIrpStackLocation(Irp); - Buffer = Irp->UserBuffer; + Buffer = Data; //DPRINT("KsPinPropertyHandler Irp %p Property %p Data %p DescriptorsCount %u Descriptor %p OutputLength %u Id %u\n", Irp, Property, Data, DescriptorsCount, Descriptor, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Property->Id); @@ -775,7 +775,7 @@ KsHandleSizedListQuery( Size = DataItemSize * DataItemsCount + sizeof(KSMULTIPLE_ITEM); /* get multiple item */ - Item = (PKSMULTIPLE_ITEM)Irp->UserBuffer; + Item = (PKSMULTIPLE_ITEM)Irp->AssociatedIrp.SystemBuffer; if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0) { diff --git a/reactos/drivers/ksfilter/ks/property.c b/reactos/drivers/ksfilter/ks/property.c index b7f93fe2ac7..cf0468292d1 100644 --- a/reactos/drivers/ksfilter/ks/property.c +++ b/reactos/drivers/ksfilter/ks/property.c @@ -136,38 +136,131 @@ KspPropertyHandler( PIO_STACK_LOCATION IoStack; NTSTATUS Status; PFNKSHANDLER PropertyHandler = NULL; - ULONG Index; + ULONG Index, InputBufferLength, OutputBufferLength, TotalSize; LPGUID Guid; /* get current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp); + /* get parameters */ + OutputBufferLength = (IoStack->Parameters.DeviceIoControl.OutputBufferLength + 7) & ~7; + InputBufferLength = IoStack->Parameters.DeviceIoControl.InputBufferLength; + + /* check for invalid buffer length size */ + if (OutputBufferLength < IoStack->Parameters.DeviceIoControl.OutputBufferLength) + { + /* unsigned overflow */ + return STATUS_INVALID_BUFFER_SIZE; + } + + /* check for integer overflow */ + if (InputBufferLength + OutputBufferLength < IoStack->Parameters.DeviceIoControl.OutputBufferLength) + { + /* overflow */ + return STATUS_INVALID_BUFFER_SIZE; + } + /* check if inputbuffer at least holds KSPROPERTY item */ if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY)) { /* invalid parameter */ - Irp->IoStatus.Information = sizeof(KSPROPERTY); return STATUS_INVALID_BUFFER_SIZE; } - /* FIXME probe the input / output buffer if from user mode */ + /* get total size */ + TotalSize = InputBufferLength + OutputBufferLength; /* get input property request */ Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; -// DPRINT("KspPropertyHandler Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM)); + /* have the parameters been checked yet */ + if (!Irp->AssociatedIrp.SystemBuffer) + { + /* is it from user mode */ + if (Irp->RequestorMode == UserMode) + { + /* probe user buffer */ + ProbeForRead(IoStack->Parameters.DeviceIoControl.Type3InputBuffer, InputBufferLength, 1); + } + + /* do we have an allocator */ + if ((Allocator) && (Property->Flags & (KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET))) + { + /* call allocator */ + Status = Allocator(Irp, TotalSize, (Property->Flags & KSPROPERTY_TYPE_GET)); + + /* check for success */ + if (!NT_SUCCESS(Status)) + return Status; + } + else + { + /* allocate buffer */ + Irp->AssociatedIrp.SystemBuffer = AllocateItem(NonPagedPool, TotalSize); + + /* sanity check */ + ASSERT(Irp->AssociatedIrp.SystemBuffer != NULL); + + /* mark irp as buffered so that changes the stream headers are propagated back */ + Irp->Flags |= IRP_DEALLOCATE_BUFFER | IRP_BUFFERED_IO; + } + + /* now copy the buffer */ + RtlCopyMemory((PVOID)((ULONG_PTR)Irp->AssociatedIrp.SystemBuffer + OutputBufferLength), IoStack->Parameters.DeviceIoControl.Type3InputBuffer, InputBufferLength); + + /* use new property buffer */ + Property = (PKSPROPERTY)((ULONG_PTR)Irp->AssociatedIrp.SystemBuffer + OutputBufferLength); + + /* is it a set operation */ + if (Property->Flags & KSPROPERTY_TYPE_SET) + { + /* for set operations, the output parameters need to be copied */ + if (Irp->RequestorMode == UserMode) + { + /* probe user parameter */ + ProbeForRead(Irp->UserBuffer, IoStack->Parameters.DeviceIoControl.OutputBufferLength, 1); + } + + /* copy parameters, needs un-aligned parameter length */ + RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Irp->UserBuffer, IoStack->Parameters.DeviceIoControl.OutputBufferLength); + } + + /* is there an output buffer */ + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength) + { + /* is it from user mode */ + if (Irp->RequestorMode == UserMode) + { + /* probe buffer for writing */ + ProbeForWrite(Irp->UserBuffer, IoStack->Parameters.DeviceIoControl.OutputBufferLength, 1); + } + + if (!Allocator || !(Property->Flags & KSPROPERTY_TYPE_GET)) + { + /* it is an input operation */ + Irp->Flags |= IRP_INPUT_OPERATION; + } + } + } + else + { + /* use new property buffer */ + Property = (PKSPROPERTY)((ULONG_PTR)Irp->AssociatedIrp.SystemBuffer + OutputBufferLength); + } + + DPRINT("KspPropertyHandler Irp %p PropertySetsCount %u PropertySet %p Allocator %p PropertyItemSize %u ExpectedPropertyItemSize %u\n", Irp, PropertySetsCount, PropertySet, Allocator, PropertyItemSize, sizeof(KSPROPERTY_ITEM)); /* sanity check */ ASSERT(PropertyItemSize == 0 || PropertyItemSize == sizeof(KSPROPERTY_ITEM)); /* find the property handler */ - Status = FindPropertyHandler(&Irp->IoStatus, PropertySet, PropertySetsCount, Property, IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Irp->UserBuffer, &PropertyHandler, &Set); + Status = FindPropertyHandler(&Irp->IoStatus, PropertySet, PropertySetsCount, Property, InputBufferLength, OutputBufferLength, Irp->AssociatedIrp.SystemBuffer, &PropertyHandler, &Set); if (NT_SUCCESS(Status) && PropertyHandler) { /* call property handler */ KSPROPERTY_SET_IRP_STORAGE(Irp) = Set; - Status = PropertyHandler(Irp, Property, Irp->UserBuffer); + Status = PropertyHandler(Irp, Property, Irp->AssociatedIrp.SystemBuffer); if (Status == STATUS_BUFFER_TOO_SMALL) { @@ -185,7 +278,7 @@ KspPropertyHandler( } /* re-call property handler */ - Status = PropertyHandler(Irp, Property, Irp->UserBuffer); + Status = PropertyHandler(Irp, Property, Irp->AssociatedIrp.SystemBuffer); } } } @@ -200,7 +293,7 @@ KspPropertyHandler( } // get output buffer - Guid = (LPGUID)Irp->UserBuffer; + Guid = (LPGUID)Irp->AssociatedIrp.SystemBuffer; // copy property guids from property sets for(Index = 0; Index < PropertySetsCount; Index++)