[MOD] STR #4099: libusb-based USB backend: USB backend crashes on USB errors

Till Kamppeter <[email protected]>
Newsgroups gmane.comp.printing.cups.bugs
Message-ID <[email protected]>
DO NOT REPLY TO THIS MESSAGE.  INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.

[STR New]

The attached patch checks the output value of all libusb function calls, so
that if one of the calls errors the backend errors out instead of crashing.

In addition, the detaching of the usblp kernel module is done in a earlier
stage of the open_device() function.

Link: http://www.cups.org/str.php?L4099
Version: 1.5.3

_______________________________________________
cups-bugs mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/cups-bugs
usb-backend-detach-usblp-earlier-crash-guards.patch (text/plain, 4.9 KB)
--- a/backend/usb-libusb.c
+++ b/backend/usb-libusb.c
@@ -600,31 +600,39 @@
     * to the device...
     */
 
+    int errcode;			/* Return value of libusb function */
     int number;				/* Interface number */
 
-    libusb_get_device_descriptor (printer->device, &devdesc);
-    libusb_get_config_descriptor (printer->device, printer->conf, &confptr);
-    number = confptr->interface[printer->iface].
-                 altsetting[printer->altset].bInterfaceNumber;
-    libusb_release_interface(printer->handle, number);
-    if (number != 0)
-      libusb_release_interface(printer->handle, 0);
+    errcode = 
+      libusb_get_config_descriptor (printer->device, printer->conf, &confptr);
+    if (errcode >= 0)
+    {
+      number = confptr->interface[printer->iface].
+	altsetting[printer->altset].bInterfaceNumber;
+      libusb_release_interface(printer->handle, number);
+      if (number != 0)
+	libusb_release_interface(printer->handle, 0);
 
-   /*
-    * Re-attach "usblp" kernel module if it was attached before using this
-    * device
-    */
+     /*
+      * Re-attach "usblp" kernel module if it was attached before using this
+      * device
+      */
+      if (printer->usblp_attached == 1)
+	if (libusb_attach_kernel_driver(printer->handle, printer->iface) < 0)
+	{
+	  errcode = libusb_get_device_descriptor (printer->device, &devdesc);
+	  if (errcode < 0)
+	    fprintf(stderr,
+		    "DEBUG: Failed to re-attach \"usblp\" kernel module\n");
+	  else
+	    fprintf(stderr,
+		    "DEBUG: Failed to re-attach \"usblp\" kernel module to "
+		    "%04x:%04x\n", devdesc.idVendor, devdesc.idProduct);
+	}
 
-    if (printer->usblp_attached == 1)
-    {
-      if (libusb_attach_kernel_driver(printer->handle, printer->iface) < 0)
-	fprintf(stderr,
-	        "DEBUG: Failed to re-attach \"usblp\" kernel module to "
-	        "%04x:%04x\n", devdesc.idVendor, devdesc.idProduct);
+      libusb_free_config_descriptor(confptr);
     }
 
-    libusb_free_config_descriptor(confptr);
-
    /*
     * Close the interface and return...
     */
@@ -694,7 +702,8 @@
       * a printer...
       */
 
-      libusb_get_device_descriptor (device, &devdesc);
+      if (libusb_get_device_descriptor (device, &devdesc) < 0)
+	continue;
 
       if (!devdesc.bNumConfigurations || !devdesc.idVendor ||
           !devdesc.idProduct)
@@ -1092,6 +1101,40 @@
   if (verbose)
     fputs("STATE: +connecting-to-device\n", stderr);
 
+  if ((errcode = libusb_get_device_descriptor (printer->device, &devdesc)) < 0)
+  {
+    fprintf(stderr, "DEBUG: Failed to get device descriptor, code: %d\n",
+	    errcode);
+    goto error;
+  }
+
+ /*
+  * Get the "usblp" kernel module out of the way. This backend only
+  * works without the module attached.
+  */
+
+  errcode = libusb_kernel_driver_active(printer->handle, printer->iface);
+  if (errcode == 0)
+    printer->usblp_attached = 0;
+  else if (errcode == 1)
+  {
+    printer->usblp_attached = 1;
+    if ((errcode =
+	 libusb_detach_kernel_driver(printer->handle, printer->iface)) < 0)
+    {
+      fprintf(stderr, "DEBUG: Failed to detach \"usblp\" module from %04x:%04x\n",
+	      devdesc.idVendor, devdesc.idProduct);
+      goto error;
+    }
+  }
+  else
+  {
+    printer->usblp_attached = 0;
+    fprintf(stderr, "DEBUG: Failed to check whether %04x:%04x has the \"usblp\" kernel module attached\n",
+	      devdesc.idVendor, devdesc.idProduct);
+    goto error;
+  }
+
  /*
   * Set the desired configuration, but only if it needs changing. Some
   * printers (e.g., Samsung) don't like libusb_set_configuration. It will
@@ -1106,8 +1149,14 @@
 		0, 0, (unsigned char *)&current, 1, 5000) < 0)
     current = 0;			/* Assume not configured */
 
-  libusb_get_device_descriptor (printer->device, &devdesc);
-  libusb_get_config_descriptor (printer->device, printer->conf, &confptr);
+  if ((errcode = 
+       libusb_get_config_descriptor (printer->device, printer->conf, &confptr))
+      < 0)
+  {
+    fprintf(stderr, "DEBUG: Failed to get config descriptor for %04x:%04x\n",
+	    devdesc.idVendor, devdesc.idProduct);
+    goto error;
+  }
   number1 = confptr->bConfigurationValue;
 
   if (number1 != current)
@@ -1127,33 +1176,6 @@
   }
 
  /*
-  * Get the "usblp" kernel module out of the way. This backend only
-  * works without the module attached.
-  */
-
-  errcode = libusb_kernel_driver_active(printer->handle, printer->iface);
-  if (errcode == 0)
-    printer->usblp_attached = 0;
-  else if (errcode == 1)
-  {
-    printer->usblp_attached = 1;
-    if ((errcode =
-	 libusb_detach_kernel_driver(printer->handle, printer->iface)) < 0)
-    {
-      fprintf(stderr, "DEBUG: Failed to detach \"usblp\" module from %04x:%04x\n",
-	      devdesc.idVendor, devdesc.idProduct);
-      goto error;
-    }
-  }
-  else
-  {
-    printer->usblp_attached = 0;
-    fprintf(stderr, "DEBUG: Failed to check whether %04x:%04x has the \"usblp\" kernel module attached\n",
-	      devdesc.idVendor, devdesc.idProduct);
-    goto error;
-  }
-
- /*
   * Claim interfaces as needed...
   */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.