summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShreesh Adiga <16567adigashreesh@gmail.com>2021-07-13 19:36:52 +0530
committerDudemanguy <random342@airmail.cc>2021-07-13 15:16:59 +0000
commitbe81470f5464abcb31095f6c86380b354a16ba2d (patch)
tree441d0a9eec5ba87dbe1c7ec62b5741c71ba2ecf2
parentd828652f248f152c5794a7d3a41e5732a5327e36 (diff)
downloadmpv-be81470f5464abcb31095f6c86380b354a16ba2d.tar.bz2
mpv-be81470f5464abcb31095f6c86380b354a16ba2d.tar.xz
audio: check ao driver init failure to avoid use after free
reinit_audio_filters_and_output function will free mpctx->ao_chain when there is a failure during audio initialization. So modify it to return -1 in case of init failure. The return value is checked to avoid use after free. Reported by Address Sanitizer when manually specifying --ao which triggers "Failed to initialize audio driver" error.
-rw-r--r--player/audio.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/player/audio.c b/player/audio.c
index 307909c260..8f1abbcc64 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -323,7 +323,7 @@ static void ao_chain_set_ao(struct ao_chain *ao_c, struct ao *ao)
mp_filter_wakeup(ao_c->ao_filter);
}
-static void reinit_audio_filters_and_output(struct MPContext *mpctx)
+static int reinit_audio_filters_and_output(struct MPContext *mpctx)
{
struct MPOpts *opts = mpctx->opts;
struct ao_chain *ao_c = mpctx->ao_chain;
@@ -360,13 +360,13 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx)
{
ao_chain_set_ao(ao_c, mpctx->ao);
talloc_free(out_fmt);
- return;
+ return 0;
}
// Wait until all played.
if (mpctx->ao && ao_is_playing(mpctx->ao)) {
talloc_free(out_fmt);
- return;
+ return 0;
}
// Format change during syncing. Force playback start early, then wait.
if (ao_c->ao_queue && mp_async_queue_get_frames(ao_c->ao_queue) &&
@@ -375,11 +375,11 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx)
mpctx->audio_status = STATUS_READY;
mp_wakeup_core(mpctx);
talloc_free(out_fmt);
- return;
+ return 0;
}
if (mpctx->audio_status == STATUS_READY) {
talloc_free(out_fmt);
- return;
+ return 0;
}
uninit_audio_out(mpctx);
@@ -447,7 +447,7 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx)
reset_audio_state(mpctx);
mp_output_chain_reset_harder(ao_c->filter);
mp_wakeup_core(mpctx); // reinit with new format next time
- return;
+ return 0;
}
MP_ERR(mpctx, "Could not open/initialize audio device -> no sound.\n");
@@ -478,12 +478,13 @@ static void reinit_audio_filters_and_output(struct MPContext *mpctx)
mp_wakeup_core(mpctx);
mp_notify(mpctx, MPV_EVENT_AUDIO_RECONFIG, NULL);
- return;
+ return 0;
init_error:
uninit_audio_chain(mpctx);
uninit_audio_out(mpctx);
error_on_track(mpctx, track);
+ return -1;
}
int init_audio_decoder(struct MPContext *mpctx, struct track *track)
@@ -853,8 +854,10 @@ void fill_audio_out_buffers(struct MPContext *mpctx)
return;
}
- if (ao_c->filter->ao_needs_update)
- reinit_audio_filters_and_output(mpctx);
+ if (ao_c->filter->ao_needs_update) {
+ if (reinit_audio_filters_and_output(mpctx) < 0)
+ return;
+ }
if (mpctx->vo_chain && ao_c->track && ao_c->track->dec &&
mp_decoder_wrapper_get_pts_reset(ao_c->track->dec))