jamulussoftware / jamulussoftware/jamulus
ASIO driver use-after-free when a device fails the capability check
Nessuno ha ancora preso questa issue.
- Lingua principale
- C
- Stelle
- 1.1k
- Fork
- 248
- Merge medio
- 2g 3h
- PR unite (30g)
- 9
Descrizione
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).
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia in src/sound/asio/sound.cpp, in CSound::LoadAndInitializeDriver(), nello specifico nel ramo di errore di CheckDeviceCapabilities(). Confronta la relativa pulizia con ASIOExit() e con il ramo in cui ASIOInit() fallisce, usando la riproduzione con il driver sintetico descritta nell’issue. Il lavoro è completato quando il percorso di errore non lascia alcun puntatore theAsioDriver pendente e la riproduzione esegue zero chiamate sull’oggetto liberato.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- cpp
- Ambito
- audio-video-rtc
- Tipo di issue
- Bug
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Stato di attività
- Ferma
- Chiarezza
- Specificata chiaramente
- Idoneità per principianti
- 35/100