NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/59944: usbdi(9): missing error branch in usbd_transfer?



>Number:         59944
>Category:       kern
>Synopsis:       usbdi(9): missing error branch in usbd_transfer?
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jan 26 03:05:00 +0000 2026
>Originator:     Taylor R Campbell
>Release:        current, 11, 10
>Organization:
The NetBSD Transferror
>Environment:
>Description:

	In 2022, while refactoring usbdi(9) internals to simplify the
	host controller interface driver and make it more coherent and
	easier to audit and catch errors, I made the following change:

@@ -406,7 +407,14 @@ usbd_transfer(struct usbd_xfer *xfer)
 
        /* xfer is not valid after the transfer method unless synchronous */
        SDT_PROBE2(usb, device, pipe, transfer__start,  pipe, xfer);
-       err = pipe->up_methods->upm_transfer(xfer);
+       do {
+               usbd_lock_pipe(pipe);
+               err = usb_insert_transfer(xfer);
+               usbd_unlock_pipe(pipe);
+               if (err)
+                       break;
+               err = pipe->up_methods->upm_transfer(xfer);
+       } while (0);
        SDT_PROBE3(usb, device, pipe, transfer__done,  pipe, xfer, err);
 
        if (err != USBD_IN_PROGRESS && err) {

	This appears to be missing

		if (err)
			break;

	after calling pipe->up_methds->upm_transfer, and the missing
	error branch is still missing to this day, although the
	surrounding code has changed a little from other refactoring
	and locking audits:

434 	do {
435 #ifdef DIAGNOSTIC
436 		xfer->ux_state = XFER_ONQU;
437 #endif
438 		SIMPLEQ_INSERT_TAIL(&pipe->up_queue, xfer, ux_next);
439 		if (pipe->up_running && pipe->up_serialise) {
440 			err = USBD_IN_PROGRESS;
441 		} else {
442 			pipe->up_running = 1;
443 			err = USBD_NORMAL_COMPLETION;
444 		}
445 		if (err)
446 			break;
447 		err = pipe->up_methods->upm_transfer(xfer);
448 	} while (0);

	https://nxr.netbsd.org/xref/src/sys/dev/usb/usbdi.c?r=1.255#434

>How-To-Repeat:

	code dissection

>Fix:

	Maybe?



Home | Main Index | Thread Index | Old Index