wdfserial: fix NULL pipe guards and divide-by-zero in read/write threads#21
Conversation
af1a888 to
a65c5b0
Compare
|
|
Added follow-up commit to address a Code 10 (device cannot start) yellow-bang observed by the customer on the QDSS MDM Data 90E7 (0000) interface after the crash fixes in this PR were applied. Root causeQDSS MDM Data has no bulk-IN endpoint, so after bug 3's guard the read thread took the new early-exit path and terminated without signaling
FixSignal all three handshake events (plus the existing Existing paths are unaffected: when a bulk-IN pipe exists, the events are cleared/reset by the normal thread body as before. |
a13ea3f to
0bb6156
Compare
|
Correction on my previous comment — I was wrong. Please disregard the proposed follow-up; the PR branch has been force-pushed back to the three original commits (HEAD is QDSS interfaces on PID 90E7 (MI_04 = QDSS MSM Data, MI_05 = QDSS MDM Data, MI_07 = QTI DPL Data) bind to So the customer's Code 10 on
Happy to help triage the QDSS side separately once we have the event log / driver binding info, but this PR can be reviewed on its own merits. |
0bb6156 to
be5bf40
Compare
QCPNP_ResetUsbPipe() calls WdfUsbTargetPipeGetIoTarget() and WdfIoTargetStop() without validating that the pipe handle is non-NULL. On multi-interface USB composite devices, certain interface functions may lack bulk IN or bulk OUT endpoints, leaving BulkIN/BulkOUT as NULL in the device context. When callers such as EvtDevicePrepareHardware or EvtFileCreate pass these NULL handles to QCPNP_ResetUsbPipe, the WDF framework raises a WDF_VIOLATION (bugcheck 0x10D) because the WDFUSBPIPE handle is invalid. Add a NULL check at the entry of QCPNP_ResetUsbPipe to return STATUS_SUCCESS early when the pipe handle is NULL, preventing the crash for all callers. Signed-off-by: Hang Zhao (QCT) <hangz@qti.qualcomm.com> Signed-off-by: hangz <hangz@qti.qualcomm.com>
Add a zero-check for pDevContext->wMaxPktSize before the modulo operation in QCWT_WriteRequestHandlerThread. When the USB bulk-OUT pipe is not yet configured (or during surprise removal / power transition), wMaxPktSize can be 0, causing a SYSTEM_SERVICE_EXCEPTION (0xc0000094 integer divide-by-zero) bugcheck. The short-circuit evaluation skips the zero-length-packet logic entirely when there is no valid pipe configuration. Fixes: QUD-1832 Signed-off-by: hangz <hangz@qti.qualcomm.com>
Add a NULL check for pDevContext->BulkIN at the start of QCRD_ReadRequestHandlerThread. When the USB device has no bulk-IN endpoint (e.g., control-only or output-only interfaces), the read thread would dereference a NULL WDFUSBPIPE handle via WdfUsbTargetPipeGetIoTarget, causing a BSOD. The thread now signals its started event and exits gracefully when BulkIN is NULL, matching the existing NULL guard pattern in the write path (QCWT_EvtIoWrite). Signed-off-by: hangz <hangz@qti.qualcomm.com>
be5bf40 to
ed30267
Compare
Bug 1 — NULL pipe in QCPNP_ResetUsbPipe
QCPNP_ResetUsbPipe() calls WdfUsbTargetPipeGetIoTarget() and WdfIoTargetStop() without validating that the pipe handle is non-NULL. On multi-interface USB composite devices, certain interface functions may lack bulk IN or bulk OUT endpoints, leaving BulkIN/BulkOUT as NULL in the device context. When callers such as EvtDevicePrepareHardware or EvtFileCreate pass these NULL handles to QCPNP_ResetUsbPipe, the WDF framework raises a WDF_VIOLATION (bugcheck 0x10D) because the WDFUSBPIPE handle is invalid.
Fix
Add a NULL check at the entry of QCPNP_ResetUsbPipe to return STATUS_SUCCESS early when the pipe handle is NULL.
Bug 2 — Integer divide-by-zero in write thread (QUD-1832)
QCWT_WriteRequestHandlerThread performs
writeParam.Parameters.Write.Length % pDevContext->wMaxPktSizeto decide whether a zero-length USB packet is needed. When the bulk-OUT pipe is not yet configured (or during surprise removal / power transition),wMaxPktSizeis 0, causing a SYSTEM_SERVICE_EXCEPTION (bugcheck 0xC0000094 — integer divide-by-zero).Crash signature:
qcwdfserial+0x1370f,rax=0x9(write length),r8=0x0(wMaxPktSize).Fix
Add
pDevContext->wMaxPktSize != 0guard before the modulo in QCWT_WriteRequestHandlerThread. C short-circuit evaluation skips the division when the packet size is zero.Bug 3 — NULL BulkIN dereference in read handler thread
QCRD_ReadRequestHandlerThread unconditionally calls
WdfUsbTargetPipeGetIoTarget(pDevContext->BulkIN)at thread start. When the USB device has no bulk-IN endpoint (e.g., control-only or output-only interfaces), BulkIN is NULL and the WDF framework dereferences an invalid handle, causing a BSOD.Fix
Add a NULL check for
pDevContext->BulkINat the top of the read handler thread. If NULL, signal the thread-started event and exit gracefully via PsTerminateSystemThread, matching the existing NULL guard pattern in the write path.Testing
Fixes: QUD-1832