
CVE-2022-25258 - Exploit de démonstration ciblant le gestionnaire de descripteurs OS du gadget USB
Le sous-système USB Gadget comporte des problèmes de sécurité dans la section de gestion des descripteurs OS de la fonction composite_setup (composite.c). Le traitement de messages de requête de contrôle correctement élaborés entraîne un crash de l'appareil en raison d'un déréférencement de pointeur nul ou d'une corruption mémoire.
La section de gestion des descripteurs OS de composite_setup pour le destinataire d'interface est implémentée comme suit.
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 est dérivée de w_value puis utilisée pour indexer le tableau usb_configuration->interface dans les fonctions count_ext_prop, len_ext_prop et fill_ext_prop. Étant donné que le tableau c->interface a une taille de MAX_CONFIG_INTERFACES (16) éléments et que la variable interface n'est validée ni dans la section de gestion des descripteurs OS de composite_setup ni dans les fonctions appelées, cela permet à un attaquant d'indexer le tableau c->interface au-delà des limites réelles. Si la variable interface a une valeur supérieure ou égale à MAX_CONFIG_INTERFACES, l'endpoint devrait être bloqué (stall).
Dans certains cas, selon le contenu mémoire réel, l'indexation au-delà du tableau c->interface peut déclencher un débordement de tampon de req->buf via fill_ext_prop lorsque w_length est supérieur à 0x0A. Si la somme de ext_prop->name_len, ext_prop->data_len, 14 et 10 dépasse int, la condition count + n >= USB_COMP_EP0_OS_DESC_BUFSIZ ne serait pas satisfaite, permettant un débordement via memcpy dans usb_ext_prop_put_binary. Cependant, la probabilité d'une telle situation semble assez faible.
De plus, les fonctions count_ext_prop, len_ext_prop et fill_ext_prop ne vérifient pas si le *usb_function récupéré depuis le tableau c->interface est réellement valide, ce qui entraîne un déréférencement de pointeur nul. Lorsque le pointeur usb_function récupéré est nul, l'endpoint devrait être bloqué.
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;
}
Les appareils Linux (et Android) exposant des gadgets USB avec prise en charge des descripteurs OS peuvent être arbitrairement mis en crash par un hôte malveillant au moyen d'un seul message de requête de contrôle.
Un correctif traitant du problème décrit a été accepté et est désormais disponible dans les versions de noyau prises en charge. Pour plus d'informations, consultez le lien ci-dessous.