[PATCH 1/6] wineusb.sys: Implement URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE.

Thomas Faber thomas.faber at reactos.org
Sat Apr 25 01:50:05 CDT 2020


I'm a bit late here, but FYI for future work:


On 2020-04-18 01:03, Zebediah Figura wrote:
> +static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device_obj, IRP *irp)
> +{
> +    IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
> +    ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
> +    struct usb_device *device = device_obj->DeviceExtension;
> +    NTSTATUS status = STATUS_NOT_IMPLEMENTED;
> +
> +    TRACE("device_obj %p, irp %p, code %#x.\n", device_obj, irp, code);
> +
> +    switch (code)
> +    {
> +        case IOCTL_INTERNAL_USB_SUBMIT_URB:
> +            status = usb_submit_urb(device, irp);
> +            break;
> +
> +        default:
> +            FIXME("Unhandled ioctl %#x (device %#x, access %#x, function %#x, method %#x).\n",
> +                    code, code >> 16, (code >> 14) & 3, (code >> 2) & 0xfff, code & 3);
> +    }
> +
> +    if (status == STATUS_PENDING)
> +    {
> +        IoMarkIrpPending(irp);

This code pattern is almost always incorrect.
If your handler function returned STATUS_PENDING, it normally means the IRP has already been added to a queue and a worker thread may pick it up and complete it concurrently.
Because IoCompleteRequest frees the memory associated with the IRP, this can therefore result in a use after free.
The correct pattern is to call IoMarkIrpPending before enqueuing the IRP.


Thanks.
-Thomas



More information about the wine-devel mailing list