CVE-2021-46986
usb: dwc3: gadget: Free gadget structure only after freeing endpoints
Severity Score
Exploit Likelihood
Affected Versions
Public Exploits
0Exploited in Wild
-Decision
Descriptions
In the Linux kernel, the following vulnerability has been resolved: usb: dwc3: gadget: Free gadget structure only after freeing endpoints As part of commit e81a7018d93a ("usb: dwc3: allocate gadget structure
dynamically") the dwc3_gadget_release() was added which will free
the dwc->gadget structure upon the device's removal when
usb_del_gadget_udc() is called in dwc3_gadget_exit(). However, simply freeing the gadget results a dangling pointer
situation: the endpoints created in dwc3_gadget_init_endpoints()
have their dep->endpoint.ep_list members chained off the list_head
anchored at dwc->gadget->ep_list. Thus when dwc->gadget is freed,
the first dwc3_ep in the list now has a dangling prev pointer and
likewise for the next pointer of the dwc3_ep at the tail of the list.
The dwc3_gadget_free_endpoints() that follows will result in a
use-after-free when it calls list_del(). This was caught by enabling KASAN and performing a driver unbind.
The recent commit 568262bf5492 ("usb: dwc3: core: Add shutdown
callback for dwc3") also exposes this as a panic during shutdown. There are a few possibilities to fix this. One could be to perform
a list_del() of the gadget->ep_list itself which removes it from
the rest of the dwc3_ep chain. Another approach is what this patch does, by splitting up the
usb_del_gadget_udc() call into its separate "del" and "put"
components. This allows dwc3_gadget_free_endpoints() to be
called before the gadget is finally freed with usb_put_gadget().
En el kernel de Linux, se resolvió la siguiente vulnerabilidad: usb: dwc3: gadget: estructura de gadget libre solo después de liberar los puntos finales. Como parte de el commit e81a7018d93a ("usb: dwc3: asignar estructura de gadget dinámicamente"), se agregó dwc3_gadget_release() que libere la estructura dwc->gadget al retirar el dispositivo cuando se llama a usb_del_gadget_udc() en dwc3_gadget_exit(). Sin embargo, simplemente liberar el gadget da como resultado una situación de puntero colgante: los puntos finales creados en dwc3_gadget_init_endpoints() tienen sus miembros dep->endpoint.ep_list encadenados fuera del list_head anclado en dwc->gadget->ep_list. Por lo tanto, cuando se libera dwc->gadget, el primer dwc3_ep de la lista ahora tiene un puntero anterior colgante y lo mismo ocurre con el siguiente puntero de dwc3_ep al final de la lista. El dwc3_gadget_free_endpoints() que sigue dará como resultado un use-after-free cuando llame a list_del(). Esto se detectó habilitando KASAN y realizando una desvinculación del controlador. La reciente confirmación 568262bf5492 ("usb: dwc3: core: Add Shutdown Callback for dwc3") también expone esto como un pánico durante el apagado. Hay algunas posibilidades para solucionar este problema. Una podría ser realizar un list_del() del propio gadget->ep_list que lo elimine del resto de la cadena dwc3_ep. Otro enfoque es lo que hace este parche, al dividir la llamada usb_del_gadget_udc() en sus componentes separados "del" y "put". Esto permite llamar a dwc3_gadget_free_endpoints() antes de que el gadget se libere finalmente con usb_put_gadget().
In the Linux kernel, the following vulnerability has been resolved: usb: dwc3: gadget: Free gadget structure only after freeing endpoints As part of commit e81a7018d93a ("usb: dwc3: allocate gadget structure dynamically") the dwc3_gadget_release() was added which will free the dwc->gadget structure upon the device's removal when usb_del_gadget_udc() is called in dwc3_gadget_exit(). However, simply freeing the gadget results a dangling pointer situation: the endpoints created in dwc3_gadget_init_endpoints() have their dep->endpoint.ep_list members chained off the list_head anchored at dwc->gadget->ep_list. Thus when dwc->gadget is freed, the first dwc3_ep in the list now has a dangling prev pointer and likewise for the next pointer of the dwc3_ep at the tail of the list. The dwc3_gadget_free_endpoints() that follows will result in a use-after-free when it calls list_del(). This was caught by enabling KASAN and performing a driver unbind. The recent commit 568262bf5492 ("usb: dwc3: core: Add shutdown callback for dwc3") also exposes this as a panic during shutdown. There are a few possibilities to fix this. One could be to perform a list_del() of the gadget->ep_list itself which removes it from the rest of the dwc3_ep chain. Another approach is what this patch does, by splitting up the usb_del_gadget_udc() call into its separate "del" and "put" components. This allows dwc3_gadget_free_endpoints() to be called before the gadget is finally freed with usb_put_gadget().
CVSS Scores
SSVC
- Decision:Track
Timeline
- 2024-02-27 CVE Reserved
- 2024-02-28 CVE Published
- 2024-12-19 CVE Updated
- 2025-01-01 EPSS Updated
- ---------- Exploited in Wild
- ---------- KEV Due Date
- ---------- First Exploit
CWE
CAPEC
References (5)
URL | Tag | Source |
---|---|---|
https://git.kernel.org/stable/c/e81a7018d93a7de31a3f121c9a7eecd0a5ec58b0 | Vuln. Introduced |
URL | Date | SRC |
---|
URL | Date | SRC |
---|
Affected Vendors, Products, and Versions
Vendor | Product | Version | Other | Status | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Vendor | Product | Version | Other | Status | <-- --> | Vendor | Product | Version | Other | Status |
Linux Search vendor "Linux" | Linux Kernel Search vendor "Linux" for product "Linux Kernel" | >= 5.10 < 5.10.38 Search vendor "Linux" for product "Linux Kernel" and version " >= 5.10 < 5.10.38" | en |
Affected
| ||||||
Linux Search vendor "Linux" | Linux Kernel Search vendor "Linux" for product "Linux Kernel" | >= 5.10 < 5.11.22 Search vendor "Linux" for product "Linux Kernel" and version " >= 5.10 < 5.11.22" | en |
Affected
| ||||||
Linux Search vendor "Linux" | Linux Kernel Search vendor "Linux" for product "Linux Kernel" | >= 5.10 < 5.12.5 Search vendor "Linux" for product "Linux Kernel" and version " >= 5.10 < 5.12.5" | en |
Affected
| ||||||
Linux Search vendor "Linux" | Linux Kernel Search vendor "Linux" for product "Linux Kernel" | >= 5.10 < 5.13 Search vendor "Linux" for product "Linux Kernel" and version " >= 5.10 < 5.13" | en |
Affected
|