Commit 3138c93
ao_coreaudio: register hotplug listener after init succeeds
ao_uninit() calls the driver's uninit() only once ao->driver_initialized
is set, i.e. after init() has succeeded, but it frees the ao either way.
init() registered the hotplug listener before the steps that can fail, so
a failed init left CoreAudio holding two property listeners whose
clientData pointed at freed memory. mpv falls back to the next ao driver,
so the process stays alive and the next device change enters hotplug_cb()
on the freed ao.
Easy to hit on macOS 26/27, where init_audiounit() fails with -50 for some
channel layouts and mpv falls back to ao_avfoundation. Under ASan this is
a heap-use-after-free in hotplug_cb() with the free attributed to
ao_uninit(); without it the crash depends on what reuses the block, since
mp_msg_level() dereferences log unconditionally.
Register after everything that can fail instead.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>1 parent e7191f2 commit 3138c93
1 file changed
Lines changed: 5 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
167 | 167 | | |
168 | 168 | | |
169 | 169 | | |
170 | | - | |
171 | | - | |
172 | | - | |
173 | 170 | | |
174 | 171 | | |
175 | 172 | | |
| |||
193 | 190 | | |
194 | 191 | | |
195 | 192 | | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
196 | 198 | | |
197 | 199 | | |
198 | 200 | | |
| |||
0 commit comments