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