jamulussoftware / jamulussoftware/jamulus
ASIO driver use-after-free when a device fails the capability check
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- C
- Sterne
- 1.1k
- Forks
- 248
- Ø Merge
- 2 T. 3 Std.
- Gemergte PRs (30 T.)
- 9
Beschreibung
Summary
Use-after-free on the ASIO SDK's global theAsioDriver pointer when a device
fails the capability check. On current main, a device that fails
CheckDeviceCapabilities() during ASIO re-init can leave a dangling global
pointer that a later re-init dereferences. Symptoms are inconsistent — hang,
crash, or silent corruption — which matches the reports in #872 and #305.
Context
- #872 (closed 2021) reported the "process doesn't get killed / ASIO4ALL red
cross lockout" symptom; the root cause was not identified then. - Discovered as part of the #3779 investigation (Windows hang with ASIO4ALL),
in which #872's defect is one of several distinct problems.
Evidence (mcfnord, on Windows — issue #3779 comment 5224437188)
One honest caveat up front: this measurement was done with a synthetic test
driver that deliberately fails the capability check, not with ASIO4ALL on real
hardware. With that said:
- This is a use-after-free, not a leak:
ASIOExit()is effectively
removeCurrentDriver()+theAsioDriver = 0. The current failure branch
only does the first of those. - Outcome is driver-dependent: ASIO4ALL's driver object is static in its
DLL and survives the COM release (→ hang / lockout); Focusrite USB
ASIO's object is heap-allocated, so the next call faults (0xC0000005). - With the synthetic driver, the stock build (
4d142945) made seven ASIO
calls on the freed object; withASIOExit(), zero.
How to reproduce
The reliable repro we have is with a synthetic driver that fails
CheckDeviceCapabilities() on demand. On real Windows hardware with ASIO4ALL
this is our best guess at hitting the same path — it is unverified:
- Select a device that fails the capability check (e.g. one that does not
support the required sample rate) while a valid device is also available. - Trigger re-init (e.g. change the audio device in the client settings).
- Re-select the previous working device.
The failure branch is hit at CSound::LoadAndInitializeDriver()
(src/sound/asio/sound.cpp) — CheckDeviceCapabilities() fails, the driver is
released via asioDrivers->removeCurrentDriver(), and the global
theAsioDriver pointer is left dangling. A subsequent re-init dereferences it.
Proposed fix
In CSound::LoadAndInitializeDriver() (src/sound/asio/sound.cpp), the
CheckDeviceCapabilities() failure branch should call ASIOExit() instead
of asioDrivers->removeCurrentDriver(), so the global pointer is nulled. The
ASIOInit()-failed branch is left alone — from reading the ASIO SDK it resets
the global pointer on that path, though I haven't instrumented it to be sure.
A ready patch exists in fork PR ann0see/jamulus#286 (one-line change + comment),
reproducing the 7-vs-0 result. This issue is opened to track the defect so the
fix is not lost if the fork PR is never reopened upstream.
Requested actions
- Review whether the failure branch should use
ASIOExit(). - If agreed, apply the fix on
main(a small, low-risk change).
⚠️ AI-generated issue — please verify
- This text is AI generated, may be wrong, and may contain inaccuracies.
- The hardware verification described below was performed by a human with an AI agent
(mcfnord, on Windows).
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne in src/sound/asio/sound.cpp bei CSound::LoadAndInitializeDriver(), genauer im Fehlerzweig von CheckDeviceCapabilities(). Vergleiche dessen Bereinigung mit ASIOExit() und dem fehlgeschlagenen ASIOInit()-Zweig und verwende dabei die im Issue beschriebene Reproduktion mit dem synthetischen Treiber. Als erledigt gilt die Aufgabe, wenn der Fehlerpfad keinen verwaisten theAsioDriver-Zeiger hinterlässt und die Reproduktion null Aufrufe auf dem freigegebenen Objekt ausführt.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- cpp
- Bereich
- audio-video-rtc
- Issue-Typ
- Bug
- Schwierigkeit
- 2/5
- Geschätzter Aufwand
- 1-3 Stunden
- Aktivitätsstatus
- Veraltet
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 35/100