
CVE-2022-25258 - Exploit dimostrativo mirato al gestore del descrittore OS del gadget USB
Il sottosistema USB Gadget include problemi di sicurezza nella sezione di gestione dei descrittori OS della funzione composite_setup (composite.c). L'elaborazione di messaggi di richiesta di trasferimento di controllo opportunamente costruiti provoca il crash del dispositivo a causa di dereferenziamento di puntatore nullo o corruzione della memoria.
La sezione di gestione dei descrittori OS di composite_setup per il destinatario dell'interfaccia è implementata come segue.
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 variabile interface è derivata da w_value e successivamente utilizzata per indicizzare l'array usb_configuration->interface nelle funzioni count_ext_prop, len_ext_prop e fill_ext_prop. Poiché l'array c->interface ha dimensione di MAX_CONFIG_INTERFACES (16) elementi e la variabile interface non viene validata né nella sezione di gestione dei descrittori OS di composite_setup né nelle funzioni chiamate, ciò permette a un attaccante di indicizzare l'array c->interface oltre i limiti effettivi. Nel caso in cui la variabile interface abbia un valore maggiore o uguale a MAX_CONFIG_INTERFACES, l'endpoint dovrebbe essere bloccato (stallato).
In alcuni casi, a seconda del contenuto effettivo della memoria, l'indicizzazione oltre l'array c->interface può innescare un buffer overflow di req->buf tramite fill_ext_prop quando wLength è maggiore di 0x0A. Se la somma di ext_prop->name_len, ext_prop->data_len, 14 e 10 causa un overflow di int, la condizione count + n >= USB_COMP_EP0_OS_DESC_BUFSIZ non verrebbe soddisfatta, consentendo un overflow tramite memcpy in usb_ext_prop_put_binary. Tuttavia, la probabilità di tale situazione sembra piuttosto bassa.
Inoltre, le funzioni count_ext_prop, len_ext_prop e fill_ext_prop mancano di validazione se il *usb_function recuperato dall'array c->interface sia effettivamente valido, causando un dereferenziamento di puntatore nullo. Quando il puntatore usb_function recuperato è nullo, l'endpoint dovrebbe essere bloccato.
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;
}
I dispositivi Linux (e Android) che espongono gadget USB con supporto per descrittori OS possono essere arbitrariamente mandati in crash da un host malevolo tramite un singolo messaggio di trasferimento di controllo.
Una patch che affronta il problema descritto è stata accettata ed è ora disponibile nelle versioni supportate del kernel. Per maggiori informazioni, consulta il link sottostante.