ChangeSet 1.1455.1.29, 2003/07/15 14:59:26-07:00, oliver@neukum.org

[PATCH] USB: fix race between open() and probe()

registering the device before setting the interface data can lead
to a null pointer being followed in open(). This patch fixes that.


 drivers/usb/class/usblp.c |   34 +++++++++++++++++-----------------
 1 files changed, 17 insertions(+), 17 deletions(-)


diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
--- a/drivers/usb/class/usblp.c	Thu Jul 17 17:04:08 2003
+++ b/drivers/usb/class/usblp.c	Thu Jul 17 17:04:08 2003
@@ -833,22 +833,15 @@
 	init_waitqueue_head(&usblp->wait);
 	usblp->ifnum = intf->altsetting->desc.bInterfaceNumber;
 
-	retval = usb_register_dev(intf, &usblp_class);
-	if (retval) {
-		err("Not able to get a minor for this device.");
-		goto abort;
-	}
-	usblp->minor = intf->minor;
-
 	usblp->writeurb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!usblp->writeurb) {
 		err("out of memory");
-		goto abort_minor;
+		goto abort;
 	}
 	usblp->readurb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!usblp->readurb) {
 		err("out of memory");
-		goto abort_minor;
+		goto abort;
 	}
 
 	/* Malloc device ID string buffer to the largest expected length,
@@ -856,7 +849,7 @@
 	 * could change in length. */
 	if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) {
 		err("out of memory for device_id_string");
-		goto abort_minor;
+		goto abort;
 	}
 
 	usblp->writebuf = usblp->readbuf = NULL;
@@ -868,19 +861,19 @@
 	if (!(usblp->writebuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE,
 				GFP_KERNEL, &usblp->writeurb->transfer_dma))) {
 		err("out of memory for write buf");
-		goto abort_minor;
+		goto abort;
 	}
 	if (!(usblp->readbuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE,
 				GFP_KERNEL, &usblp->readurb->transfer_dma))) {
 		err("out of memory for read buf");
-		goto abort_minor;
+		goto abort;
 	}
 
 	/* Allocate buffer for printer status */
 	usblp->statusbuf = kmalloc(STATUS_BUF_SIZE, GFP_KERNEL);
 	if (!usblp->statusbuf) {
 		err("out of memory for statusbuf");
-		goto abort_minor;
+		goto abort;
 	}
 
 	/* Lookup quirks for this printer. */
@@ -894,12 +887,12 @@
 		dbg("incompatible printer-class device 0x%4.4X/0x%4.4X",
 			dev->descriptor.idVendor,
 			dev->descriptor.idProduct);
-		goto abort_minor;
+		goto abort;
 	}
 
 	/* Setup the selected alternate setting and endpoints. */
 	if (usblp_set_protocol(usblp, protocol) < 0)
-		goto abort_minor;
+		goto abort;
 
 	/* Retrieve and store the device ID string. */
 	usblp_cache_device_id_string(usblp);
@@ -920,10 +913,17 @@
 
 	usblp->present = 1;
 
+	retval = usb_register_dev(intf, &usblp_class);
+	if (retval) {
+		err("Not able to get a minor for this device.");
+		goto abort_intfdata;
+	}
+	usblp->minor = intf->minor;
+
 	return 0;
 
-abort_minor:
-	usb_deregister_dev(intf, &usblp_class);
+abort_intfdata:
+	usb_set_intfdata (intf, NULL);
 abort:
 	if (usblp) {
 		if (usblp->writebuf)
