
CVE-2022-25258 - Demo-Exploit, der auf den os-Deskriptor-Handler des usb-Gadgets abzielt.
Das USB-Gadget-Subsystem enthält Sicherheitsprobleme im OS-Deskriptor-Handling-Abschnitt der composite_setup-Funktion (composite.c). Die Verarbeitung von sorgfältig konstruierten Steuertransfer-Anforderungsnachrichten führt zu einem Geräteabsturz aufgrund einer Nullzeiger-Dereferenzierung oder Speicherbeschädigung.
Der OS-Deskriptor-Handling-Abschnitt von composite_setup für den Interface-Empfänger ist wie folgt implementiert.
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;
Die Variable interface wird aus w_value abgeleitet und später verwendet, um das usb_configuration->interface-Array in den Funktionen count_ext_prop, len_ext_prop und fill_ext_prop zu indizieren. Da das c->interface-Array die Größe von MAX_CONFIG_INTERFACES (16) Elementen hat und die Variable interface weder im OS-Deskriptor-Handling-Abschnitt von composite_setup noch in den aufgerufenen Funktionen validiert wird, ermöglicht dies einem Angreifer, das c->interface-Array über die tatsächlichen Grenzen hinaus zu indizieren. Falls die Variable interface einen Wert größer oder gleich MAX_CONFIG_INTERFACES hat, sollte der Endpunkt gestoppt (stalled) werden.
In bestimmten Fällen kann das Indizieren über das c->interface-Array hinaus, abhängig vom tatsächlichen Speicherinhalt, einen Pufferüberlauf von req->buf über fill_ext_prop auslösen, wenn wLength größer als 0x0A ist. Wenn die Summe von ext_prop->name_len, ext_prop->data_len, 14 und 10 den int-Bereich überläuft, wäre die Bedingung count + n >= USB_COMP_EP0_OS_DESC_BUFSIZ nicht erfüllt, was einen Überlauf über memcpy in usb_ext_prop_put_binary ermöglicht. Die Wahrscheinlichkeit einer solchen Situation scheint jedoch recht gering.
Des Weiteren fehlt in den Funktionen count_ext_prop, len_ext_prop und fill_ext_prop eine Überprüfung, ob der aus dem c->interface-Array abgerufene *usb_function tatsächlich gültig ist, was zu einer Nullzeiger-Dereferenzierung führt. Wenn der abgerufene usb_function-Zeiger null ist, sollte der Endpunkt gestoppt (stalled) werden.
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;
}
Linux- (und Android-)Geräte, die USB-Gadgets mit OS-Deskriptor-Unterstützung bereitstellen, können von einem böswilligen Host durch eine einzelne Steuertransfer-Nachricht beliebig zum Absturz gebracht werden.
Ein Patch, der das beschriebene Problem behebt, wurde akzeptiert und ist nun in unterstützten Kernel-Versionen verfügbar. Weitere Informationen finden Sie unter dem folgenden Link.