Re: USB vulnerabilities

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

 



Dmitry,

Attached are the patches Anirudh created.  Also, I have added him to the
thread if you have any questions or comments for him.

Rosie

On Thu Jul 28 2016 16:58:27 GMT-0400 (EDT), roswest wrote:
> Dmitry,
> 
> Tomorrow is his last day, but he is going to try to accomplish that.
> 
> Rosie
> 
> On Thu Jul 28 2016 13:48:48 GMT-0400 (EDT), Dmitry Torokhov wrote:
>> Hi Rosie,
>>
>> On Thu, Jul 28, 2016 at 12:23:09PM -0400, roswest wrote:
>>>
>>> Dmitry,
>>>
>>> Hi, I am an engineer at Cisco Systems, and this summer we tasked some
>>> interns with performing USB fuzzing. One of the interns, Anirudh Bagde,
>>> was able to crash the USB stack due to an error in the iforce module and
>>> discovered a buffer over-read in the usbtouchscreen module.  Please see
>>> the attachment for details.
>>
>> Thank you for the report. Any chance Anirudh could provide patches to
>> fix these issues as well?
>>
>> Thanks!
>>
> 
--- a/drivers/input/joystick/iforce/iforce-usb.c	2016-07-29 15:02:47.602630504 -0400
+++ b/drivers/input/joystick/iforce/iforce-usb.c	2016-07-29 15:02:32.946812336 -0400
@@ -135,12 +135,23 @@
 {
 	struct usb_device *dev = interface_to_usbdev(intf);
 	struct usb_host_interface *interface;
-	struct usb_endpoint_descriptor *epirq, *epout;
+	struct usb_endpoint_descriptor *epirq = NULL, *epout = NULL;
 	struct iforce *iforce;
-	int err = -ENOMEM;
+	int i, err = -ENOMEM;
 
 	interface = intf->cur_altsetting;
 
+	for (i = 0; i < interface->desc.bNumEndpoints; i++) {
+		if (!epirq &&
+		    usb_endpoint_dir_in(&interface->endpoint[i].desc))
+			epirq = &interface->endpoint[i].desc;
+		if (!epout &&
+		    usb_endpoint_dir_out(&interface->endpoint[i].desc))
+			epout = &interface->endpoint[i].desc;
+	}
+	if (!epirq || !epout)
+		return -ENODEV;
+
 	epirq = &interface->endpoint[0].desc;
 	epout = &interface->endpoint[1].desc;
 
--- a/drivers/input/touchscreen/usbtouchscreen.c	2016-07-29 17:33:31.430429835 -0400
+++ b/drivers/input/touchscreen/usbtouchscreen.c	2016-07-29 17:31:57.795591496 -0400
@@ -85,7 +85,8 @@
 	 */
 	bool irq_always;
 
-	void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len);
+	void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt,
+			     unsigned int len);
 
 	/*
 	 * used to get the packet len. possible return values:
@@ -95,7 +96,8 @@
 	 */
 	int  (*get_pkt_len) (unsigned char *pkt, int len);
 
-	int  (*read_data)   (struct usbtouch_usb *usbtouch, unsigned char *pkt);
+	int  (*read_data)   (struct usbtouch_usb *usbtouch, unsigned char *pkt,
+			     unsigned int len);
 	int  (*alloc)       (struct usbtouch_usb *usbtouch);
 	int  (*init)        (struct usbtouch_usb *usbtouch);
 	void (*exit)	    (struct usbtouch_usb *usbtouch);
@@ -275,7 +277,8 @@
 	return ret;
 }
 
-static int e2i_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int e2i_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			 unsigned int len)
 {
 	int tmp = (pkt[0] << 8) | pkt[1];
 	dev->x  = (pkt[2] << 8) | pkt[3];
@@ -343,7 +346,8 @@
 	return ret;
 }
 
-static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			    unsigned int len)
 {
 	if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT)
 		return 0;
@@ -387,7 +391,8 @@
 #define ETOUCH_PKT_TYPE_REPT2		0xB0
 #define ETOUCH_PKT_TYPE_DIAG		0x0A
 
-static int etouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int etouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			    unsigned int len)
 {
 	if ((pkt[0] & ETOUCH_PKT_TYPE_MASK) != ETOUCH_PKT_TYPE_REPT &&
 		(pkt[0] & ETOUCH_PKT_TYPE_MASK) != ETOUCH_PKT_TYPE_REPT2)
@@ -422,7 +427,8 @@
  * PanJit Part
  */
 #ifdef CONFIG_TOUCHSCREEN_USB_PANJIT
-static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			    unsigned int len)
 {
 	dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1];
 	dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3];
@@ -442,7 +448,8 @@
 #define MTOUCHUSB_RESET                 7
 #define MTOUCHUSB_REQ_CTRLLR_ID         10
 
-static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			    unsigned int len)
 {
 	if (hwcalib_xy) {
 		dev->x = (pkt[4] << 8) | pkt[3];
@@ -501,7 +508,8 @@
  * ITM Part
  */
 #ifdef CONFIG_TOUCHSCREEN_USB_ITM
-static int itm_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int itm_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			 unsigned int len)
 {
 	int touch;
 	/*
@@ -538,7 +546,8 @@
 #ifndef MULTI_PACKET
 #define MULTI_PACKET
 #endif
-static int eturbo_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int eturbo_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			    unsigned int len)
 {
 	unsigned int shift;
 
@@ -569,7 +578,8 @@
  * Gunze part
  */
 #ifdef CONFIG_TOUCHSCREEN_USB_GUNZE
-static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			   unsigned int len)
 {
 	if (!(pkt[0] & 0x80) || ((pkt[1] | pkt[2] | pkt[3]) & 0x80))
 		return 0;
@@ -655,7 +665,8 @@
 }
 
 
-static int dmc_tsc10_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int dmc_tsc10_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			       unsigned int len)
 {
 	dev->x = ((pkt[2] & 0x03) << 8) | pkt[1];
 	dev->y = ((pkt[4] & 0x03) << 8) | pkt[3];
@@ -670,7 +681,8 @@
  * IRTOUCH Part
  */
 #ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH
-static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int irtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			     unsigned int len)
 {
 	dev->x = (pkt[3] << 8) | pkt[2];
 	dev->y = (pkt[5] << 8) | pkt[4];
@@ -684,7 +696,8 @@
  * ET&T TC5UH/TC4UM part
  */
 #ifdef CONFIG_TOUCHSCREEN_USB_ETT_TC45USB
-static int tc45usb_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int tc45usb_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			     unsigned int len)
 {
 	dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1];
 	dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3];
@@ -710,7 +723,8 @@
 	return 0;
 }
 
-static int idealtek_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int idealtek_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			      unsigned int len)
 {
 	switch (pkt[0] & 0x98) {
 	case 0x88:
@@ -737,7 +751,8 @@
  * General Touch Part
  */
 #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH
-static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+				   unsigned int len)
 {
 	dev->x = (pkt[2] << 8) | pkt[1];
 	dev->y = (pkt[4] << 8) | pkt[3];
@@ -752,7 +767,8 @@
  * GoTop Part
  */
 #ifdef CONFIG_TOUCHSCREEN_USB_GOTOP
-static int gotop_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int gotop_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			   unsigned int len)
 {
 	dev->x = ((pkt[1] & 0x38) << 4) | pkt[2];
 	dev->y = ((pkt[1] & 0x07) << 7) | pkt[3];
@@ -766,7 +782,8 @@
  * JASTEC Part
  */
 #ifdef CONFIG_TOUCHSCREEN_USB_JASTEC
-static int jastec_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int jastec_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			    unsigned int len)
 {
 	dev->x = ((pkt[0] & 0x3f) << 6) | (pkt[2] & 0x3f);
 	dev->y = ((pkt[1] & 0x3f) << 6) | (pkt[3] & 0x3f);
@@ -780,7 +797,8 @@
  * Zytronic Part
  */
 #ifdef CONFIG_TOUCHSCREEN_USB_ZYTRONIC
-static int zytronic_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int zytronic_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			      unsigned int len)
 {
 	struct usb_interface *intf = dev->interface;
 
@@ -964,7 +982,8 @@
 	kfree(priv);
 }
 
-static int nexio_read_data(struct usbtouch_usb *usbtouch, unsigned char *pkt)
+static int nexio_read_data(struct usbtouch_usb *usbtouch, unsigned char *pkt,
+			   unsigned int len)
 {
 	struct nexio_touch_packet *packet = (void *) pkt;
 	struct nexio_priv *priv = usbtouch->priv;
@@ -977,6 +996,11 @@
 	if ((pkt[0] & 0xe0) != 0xe0)
 		return 0;
 
+	if (data_len > len)
+		data_len = len;
+	if (x_len + y_len > data_len)
+		return 0;
+
 	if (data_len > 0xff)
 		data_len -= 0x100;
 	if (x_len > 0xff)
@@ -1055,7 +1079,8 @@
 
 #ifdef CONFIG_TOUCHSCREEN_USB_ELO
 
-static int elo_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+static int elo_read_data(struct usbtouch_usb *dev, unsigned char *pkt,
+			 unsigned int len)
 {
 	dev->x = (pkt[3] << 8) | pkt[2];
 	dev->y = (pkt[5] << 8) | pkt[4];
@@ -1072,7 +1097,7 @@
  */
 #ifdef MULTI_PACKET
 static void usbtouch_process_multi(struct usbtouch_usb *usbtouch,
-				   unsigned char *pkt, int len);
+				   unsigned char *pkt, unsigned int len);
 #endif
 
 static struct usbtouch_device_info usbtouch_dev_info[] = {
@@ -1303,11 +1328,11 @@
  * Generic Part
  */
 static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch,
-                                 unsigned char *pkt, int len)
+                                 unsigned char *pkt, unsigned int len)
 {
 	struct usbtouch_device_info *type = usbtouch->type;
 
-	if (!type->read_data(usbtouch, pkt))
+	if (!type->read_data(usbtouch, pkt, len))
 			return;
 
 	input_report_key(usbtouch->input, BTN_TOUCH, usbtouch->touch);
@@ -1327,7 +1352,7 @@
 
 #ifdef MULTI_PACKET
 static void usbtouch_process_multi(struct usbtouch_usb *usbtouch,
-                                   unsigned char *pkt, int len)
+                                   unsigned char *pkt, unsigned int len)
 {
 	unsigned char *buffer;
 	int pkt_len, pos, buf_len, tmp;

Attachment: signature.asc
Description: OpenPGP digital signature


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux