1From 128c16a682034263eb519c89bc0934eeb6fa8cfa Mon Sep 17 00:00:00 2001 2From: Javier Martinez Canillas <javierm@redhat.com> 3Date: Fri, 11 Dec 2020 19:19:21 +0100 4Subject: [PATCH] usb: Avoid possible out-of-bound accesses caused by malicious 5 devices 6 7The maximum number of configurations and interfaces are fixed but there is 8no out-of-bound checking to prevent a malicious USB device to report large 9values for these and cause accesses outside the arrays' memory. 10 11Fixes: CVE-2020-25647 12 13Reported-by: Joseph Tartaro <joseph.tartaro@ioactive.com> 14Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> 15Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> 16Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> 17Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com> 18--- 19 grub-core/bus/usb/usb.c | 15 ++++++++++++--- 20 include/grub/usb.h | 10 +++++++--- 21 2 files changed, 19 insertions(+), 6 deletions(-) 22 23diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c 24index 8da5e4c..7cb3cc2 100644 25--- a/grub-core/bus/usb/usb.c 26+++ b/grub-core/bus/usb/usb.c 27@@ -75,6 +75,9 @@ grub_usb_controller_iterate (grub_usb_controller_iterate_hook_t hook, 28 grub_usb_err_t 29 grub_usb_clear_halt (grub_usb_device_t dev, int endpoint) 30 { 31+ if (endpoint >= GRUB_USB_MAX_TOGGLE) 32+ return GRUB_USB_ERR_BADDEVICE; 33+ 34 dev->toggle[endpoint] = 0; 35 return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT 36 | GRUB_USB_REQTYPE_STANDARD 37@@ -134,10 +137,10 @@ grub_usb_device_initialize (grub_usb_device_t dev) 38 return err; 39 descdev = &dev->descdev; 40 41- for (i = 0; i < 8; i++) 42+ for (i = 0; i < GRUB_USB_MAX_CONF; i++) 43 dev->config[i].descconf = NULL; 44 45- if (descdev->configcnt == 0) 46+ if (descdev->configcnt == 0 || descdev->configcnt > GRUB_USB_MAX_CONF) 47 { 48 err = GRUB_USB_ERR_BADDEVICE; 49 goto fail; 50@@ -172,6 +175,12 @@ grub_usb_device_initialize (grub_usb_device_t dev) 51 /* Skip the configuration descriptor. */ 52 pos = dev->config[i].descconf->length; 53 54+ if (dev->config[i].descconf->numif > GRUB_USB_MAX_IF) 55+ { 56+ err = GRUB_USB_ERR_BADDEVICE; 57+ goto fail; 58+ } 59+ 60 /* Read all interfaces. */ 61 for (currif = 0; currif < dev->config[i].descconf->numif; currif++) 62 { 63@@ -217,7 +226,7 @@ grub_usb_device_initialize (grub_usb_device_t dev) 64 65 fail: 66 67- for (i = 0; i < 8; i++) 68+ for (i = 0; i < GRUB_USB_MAX_CONF; i++) 69 grub_free (dev->config[i].descconf); 70 71 return err; 72diff --git a/include/grub/usb.h b/include/grub/usb.h 73index 512ae1d..6475c55 100644 74--- a/include/grub/usb.h 75+++ b/include/grub/usb.h 76@@ -23,6 +23,10 @@ 77 #include <grub/usbdesc.h> 78 #include <grub/usbtrans.h> 79 80+#define GRUB_USB_MAX_CONF 8 81+#define GRUB_USB_MAX_IF 32 82+#define GRUB_USB_MAX_TOGGLE 256 83+ 84 typedef struct grub_usb_device *grub_usb_device_t; 85 typedef struct grub_usb_controller *grub_usb_controller_t; 86 typedef struct grub_usb_controller_dev *grub_usb_controller_dev_t; 87@@ -167,7 +171,7 @@ struct grub_usb_configuration 88 struct grub_usb_desc_config *descconf; 89 90 /* Interfaces associated to this configuration. */ 91- struct grub_usb_interface interf[32]; 92+ struct grub_usb_interface interf[GRUB_USB_MAX_IF]; 93 }; 94 95 struct grub_usb_hub_port 96@@ -191,7 +195,7 @@ struct grub_usb_device 97 struct grub_usb_controller controller; 98 99 /* Device configurations (after opening the device). */ 100- struct grub_usb_configuration config[8]; 101+ struct grub_usb_configuration config[GRUB_USB_MAX_CONF]; 102 103 /* Device address. */ 104 int addr; 105@@ -203,7 +207,7 @@ struct grub_usb_device 106 int initialized; 107 108 /* Data toggle values (used for bulk transfers only). */ 109- int toggle[256]; 110+ int toggle[GRUB_USB_MAX_TOGGLE]; 111 112 /* Used by libusb wrapper. Schedulded for removal. */ 113 void *data; 114-- 1152.14.2 116 117