CVE-2026-43327
Beschrijving NL
In de Linux kernel is de volgende kwetsbaarheid verholpen:
USB: dummy-hcd: Fix vergrendelings-/synchronisatiefout
Syzbot-testen konden een adresseringsuitzondering en crash veroorzaken
in de usb_gadget_udc_reset() routine in
drivers/usb/gadgets/udc/core.c, als gevolg van het feit dat de
routine werd aangeroepen met een tweede ("driver") argument van NULL. Het slechte
beller was set_link_state() in dummy_hcd.c, en het probleem ontstond
vanwege een race tussen een USB-reset en het loskoppelen van de bestuurder. Dit soort races hadden niet mogelijk mogen zijn; commit
7dbd8f4cabd9 ("USB: dummy-hcd: foutieve synchronisatiewijziging oplossen"),
samen met een paar follow-up commits, is speciaal geschreven om te voorkomen dat
ze. Het blijkt dat er (ten minste) twee fouten achterblijven in
de code. Een andere patch zal de tweede fout aanpakken; deze is
bezorgd over het eerste. De fout die verantwoordelijk is voor de syzbot-crash is opgetreden omdat de
stop_activity() routine zal soms dalen en dan opnieuw de
dum->lock spinlock. Er vindt een oproep tot stop_activity() plaats in
set_link_state() bij het hanteren van een geëmuleerde USB-reset, na de test
van dum->ints_enabled en voor de toename van dum->callback_usage. Hierdoor kon een andere thread (een chauffeur loskoppelen) binnensluipen en
pak de spinlock en wis vervolgens dum- >ints_enabled en dum->driver. Normaal gesproken zou deze andere thread moeten wachten op dum->callback_usage
om naar 0 te gaan voordat het dum- >driver zou wissen, maar in dit geval
hoefde niet te wachten omdat dum->callback_usage nog niet was
verhoogd. De oplossing is om dum- >callback_usage_before_ calling te verhogen
stop_activity() in plaats van erna. Vervolgens maakt de draad het los
zal dum- >driver niet wissen tot na het telefoontje naar
usb_gadget_udc_reset() keert veilig terug endum- >callback_usage is
opnieuw verlaagd.
Origineel (Engels) tonen
In the Linux kernel, the following vulnerability has been resolved:
USB: dummy-hcd: Fix locking/synchronization error
Syzbot testing was able to provoke an addressing exception and crash
in the usb_gadget_udc_reset() routine in
drivers/usb/gadgets/udc/core.c, resulting from the fact that the
routine was called with a second ("driver") argument of NULL. The bad
caller was set_link_state() in dummy_hcd.c, and the problem arose
because of a race between a USB reset and driver unbind.
These sorts of races were not supposed to be possible; commit
7dbd8f4cabd9 ("USB: dummy-hcd: Fix erroneous synchronization change"),
along with a few followup commits, was written specifically to prevent
them. As it turns out, there are (at least) two errors remaining in
the code. Another patch will address the second error; this one is
concerned with the first.
The error responsible for the syzbot crash occurred because the
stop_activity() routine will sometimes drop and then re-acquire the
dum->lock spinlock. A call to stop_activity() occurs in
set_link_state() when handling an emulated USB reset, after the test
of dum->ints_enabled and before the increment of dum->callback_usage.
This allowed another thread (doing a driver unbind) to sneak in and
grab the spinlock, and then clear dum->ints_enabled and dum->driver.
Normally this other thread would have to wait for dum->callback_usage
to go down to 0 before it would clear dum->driver, but in this case it
didn't have to wait since dum->callback_usage had not yet been
incremented.
The fix is to increment dum->callback_usage _before_ calling
stop_activity() instead of after. Then the thread doing the unbind
will not clear dum->driver until after the call to
usb_gadget_udc_reset() safely returns and dum->callback_usage has been
decremented again.