[PATCH 04/14] usb: dwc2: host: fix use of qtd after free in desc dma mode

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

 



When completing non isoc xfer, dwc2_complete_non_isoc_xfer_ddma()
is relying on qtd->n_desc to process the corresponding number of
descriptors.

During the processing of these descriptors, qtd could be unlinked
and freed if xfer is done and urb is no more in progress.

In this case, dwc2_complete_non_isoc_xfer_ddma() will read again
qtd->n_desc whereas qtd has been freed. This will lead to unpredictable
results since qtd->n_desc is no more valid value.

To avoid this error, return a result != 0 in dwc2_process_non_isoc_desc(),
so that dwc2_complete_non_isoc_xfer_ddma() stops desc processing.

This has been seen with Slub debug enabled.

Signed-off-by: Gregory Herrero <gregory.herrero@xxxxxxxxx>
---
 drivers/usb/dwc2/hcd_ddma.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c
index 5f72656..4801e69 100644
--- a/drivers/usb/dwc2/hcd_ddma.c
+++ b/drivers/usb/dwc2/hcd_ddma.c
@@ -1033,7 +1033,10 @@ static int dwc2_process_non_isoc_desc(struct dwc2_hsotg *hsotg,
 	failed = dwc2_update_non_isoc_urb_state_ddma(hsotg, chan, qtd, dma_desc,
 						     halt_status, n_bytes,
 						     xfer_done);
-	if (failed || (*xfer_done && urb->status != -EINPROGRESS)) {
+	if (*xfer_done && urb->status != -EINPROGRESS)
+		failed = 1;
+
+	if (failed) {
 		dwc2_host_complete(hsotg, qtd, urb->status);
 		dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh);
 		dev_vdbg(hsotg->dev, "failed=%1x xfer_done=%1x status=%08x\n",
-- 
2.6.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux