[PATCH 1/1]usb: check NULL stream pointer

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

 



>From 109b59f272890bcc662f1bdf22175eba489f4a48 Mon Sep 17 00:00:00 2001
From: Jun Nie <njun@xxxxxxxxxxx>
Date: Tue, 7 Dec 2010 14:00:55 +0800
Subject: [PATCH] usb: fix stream reference after it is freed

Signed-off-by: Jun Nie <njun@xxxxxxxxxxx>
---
 drivers/usb/host/ehci-sched.c |   18 ++++++++++++++----
 1 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index d9f78eb..cc92d13 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1685,6 +1685,7 @@ itd_complete (
 	struct ehci_iso_stream			*stream = itd->stream;
 	struct usb_device			*dev;
 	unsigned				retval = false;
+	unsigned				stream_freed = 0;

 	/* for each uframe with a packet */
 	for (uframe = 0; uframe < 8; uframe++) {
@@ -1748,6 +1749,8 @@ itd_complete (
 			dev->devpath, stream->bEndpointAddress & 0x0f,
 			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
 	}
+	if (1 == stream->refcount)
+		stream_freed = 1;
 	iso_stream_put (ehci, stream);

 done:
@@ -1755,8 +1758,10 @@ done:
 	if (ehci->clock_frame != itd->frame || itd->index[7] != -1) {
 		/* OK to recycle this ITD now. */
 		itd->stream = NULL;
-		list_move(&itd->itd_list, &stream->free_list);
-		iso_stream_put(ehci, stream);
+		if (!stream_freed) {
+			list_move(&itd->itd_list, &stream->free_list);
+			iso_stream_put(ehci, stream);
+		}
 	} else {
 		/* HW might remember this ITD, so we can't recycle it yet.
 		 * Move it to a safe place until a new frame starts.
@@ -2086,6 +2091,7 @@ sitd_complete (
 	struct ehci_iso_stream			*stream = sitd->stream;
 	struct usb_device			*dev;
 	unsigned				retval = false;
+	unsigned				stream_freed = 0;

 	urb_index = sitd->index;
 	desc = &urb->iso_frame_desc [urb_index];
@@ -2133,6 +2139,8 @@ sitd_complete (
 			dev->devpath, stream->bEndpointAddress & 0x0f,
 			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
 	}
+	if (1 == stream->refcount)
+		stream_freed = 1;
 	iso_stream_put (ehci, stream);

 done:
@@ -2140,8 +2148,10 @@ done:
 	if (ehci->clock_frame != sitd->frame) {
 		/* OK to recycle this SITD now. */
 		sitd->stream = NULL;
-		list_move(&sitd->sitd_list, &stream->free_list);
-		iso_stream_put(ehci, stream);
+		if (!stream_freed) {
+			list_move(&sitd->sitd_list, &stream->free_list);
+			iso_stream_put(ehci, stream);
+		}
 	} else {
 		/* HW might remember this SITD, so we can't recycle it yet.
 		 * Move it to a safe place until a new frame starts.
-- 
1.7.0.4
From 109b59f272890bcc662f1bdf22175eba489f4a48 Mon Sep 17 00:00:00 2001
From: Jun Nie <njun@xxxxxxxxxxx>
Date: Tue, 7 Dec 2010 14:00:55 +0800
Subject: [PATCH] usb: fix stream reference after it is freed

Signed-off-by: Jun Nie <njun@xxxxxxxxxxx>
---
 drivers/usb/host/ehci-sched.c |   18 ++++++++++++++----
 1 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index d9f78eb..cc92d13 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1685,6 +1685,7 @@ itd_complete (
 	struct ehci_iso_stream			*stream = itd->stream;
 	struct usb_device			*dev;
 	unsigned				retval = false;
+	unsigned				stream_freed = 0;
 
 	/* for each uframe with a packet */
 	for (uframe = 0; uframe < 8; uframe++) {
@@ -1748,6 +1749,8 @@ itd_complete (
 			dev->devpath, stream->bEndpointAddress & 0x0f,
 			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
 	}
+	if (1 == stream->refcount)
+		stream_freed = 1;
 	iso_stream_put (ehci, stream);
 
 done:
@@ -1755,8 +1758,10 @@ done:
 	if (ehci->clock_frame != itd->frame || itd->index[7] != -1) {
 		/* OK to recycle this ITD now. */
 		itd->stream = NULL;
-		list_move(&itd->itd_list, &stream->free_list);
-		iso_stream_put(ehci, stream);
+		if (!stream_freed) {
+			list_move(&itd->itd_list, &stream->free_list);
+			iso_stream_put(ehci, stream);
+		}
 	} else {
 		/* HW might remember this ITD, so we can't recycle it yet.
 		 * Move it to a safe place until a new frame starts.
@@ -2086,6 +2091,7 @@ sitd_complete (
 	struct ehci_iso_stream			*stream = sitd->stream;
 	struct usb_device			*dev;
 	unsigned				retval = false;
+	unsigned				stream_freed = 0;
 
 	urb_index = sitd->index;
 	desc = &urb->iso_frame_desc [urb_index];
@@ -2133,6 +2139,8 @@ sitd_complete (
 			dev->devpath, stream->bEndpointAddress & 0x0f,
 			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
 	}
+	if (1 == stream->refcount)
+		stream_freed = 1;
 	iso_stream_put (ehci, stream);
 
 done:
@@ -2140,8 +2148,10 @@ done:
 	if (ehci->clock_frame != sitd->frame) {
 		/* OK to recycle this SITD now. */
 		sitd->stream = NULL;
-		list_move(&sitd->sitd_list, &stream->free_list);
-		iso_stream_put(ehci, stream);
+		if (!stream_freed) {
+			list_move(&sitd->sitd_list, &stream->free_list);
+			iso_stream_put(ehci, stream);
+		}
 	} else {
 		/* HW might remember this SITD, so we can't recycle it yet.
 		 * Move it to a safe place until a new frame starts.
-- 
1.7.0.4


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

  Powered by Linux