
CVE-2022-25258 - Exploit de demostración dirigido a usb gadget's os descriptor handler
El subsistema USB Gadget incluye problemas de seguridad en la sección de manejo de descriptores de sistema operativo (OS) de la función composite_setup (composite.c). El procesamiento de mensajes de solicitud de transferencia de control debidamente elaborados provoca un bloqueo del dispositivo debido a una desreferencia de puntero nulo o una corrupción de memoria.
La sección de manejo de descriptores de OS de composite_setup para el destinatario de interfaz se implementa de la siguiente manera.
case USB_RECIP_INTERFACE:
if (w_index != 0x5 || (w_value >> 8))
break;
interface = w_value & 0xFF;
buf[6] = w_index;
count = count_ext_prop(os_desc_cfg,
interface);
put_unaligned_le16(count, buf + 8);
count = len_ext_prop(os_desc_cfg,
interface);
put_unaligned_le32(count, buf);
value = w_length;
if (w_length > 0x0A) {
value = fill_ext_prop(os_desc_cfg,
interface, buf);
if (value >= 0)
value = min_t(u16, w_length, value);
}
break;
La variable interface se deriva de w_value y posteriormente se utiliza para indexar el arreglo usb_configuration->interface en las funciones count_ext_prop, len_ext_prop y fill_ext_prop. Dado que el arreglo c->interface tiene un tamaño de MAX_CONFIG_INTERFACES (16) elementos y la variable interface no se valida ni en la sección de manejo de descriptores de OS de composite_setup ni en las funciones llamadas, esto permite a un atacante indexar el arreglo c->interface más allá de los límites reales. En caso de que la variable interface tenga un valor mayor o igual a MAX_CONFIG_INTERFACES, se debería detener el endpoint.
En ciertos casos, dependiendo del contenido de memoria real, la indexación más allá del arreglo c->interface puede desencadenar un desbordamiento de búfer de req->buf a través de fill_ext_prop cuando wLength es mayor que 0x0A. Si la suma de ext_prop->name_len, ext_prop->data_len, 14 y 10 desborda int, la condición count + n >= USB_COMP_EP0_OS_DESC_BUFSIZ no se cumpliría, permitiendo el desbordamiento mediante memcpy en usb_ext_prop_put_binary. Sin embargo, la probabilidad de tal situación parece bastante baja.
Además, las funciones count_ext_prop, len_ext_prop y fill_ext_prop carecen de validación si el *usb_function recuperado del arreglo c->interface es realmente válido, lo que resulta en una desreferencia de puntero nulo. Cuando el puntero usb_function recuperado es nulo, se debería detener el endpoint.
static int count_ext_prop(struct usb_configuration *c, int interface)
{
struct usb_function *f;
int j;
f = c->interface[interface];
for (j = 0; j < f->os_desc_n; ++j) {
struct usb_os_desc *d;
if (interface != f->os_desc_table[j].if_id)
continue;
d = f->os_desc_table[j].os_desc;
if (d && d->ext_compat_id)
return d->ext_prop_count;
}
return 0;
}
Los dispositivos Linux (y Android) que exponen gadgets USB con soporte de descriptores de OS pueden ser bloqueados arbitrariamente por un host malicioso mediante un único mensaje de transferencia de control.
Se aceptó un parche que soluciona el problema descrito y ahora está disponible en las versiones compatibles del kernel. Para más información, consulte el enlace a continuación.
USB: gadget: valida las solicitudes de descriptores de OS de interfaz