From addbcc64879c44f002aeb7fa212bf985a8fa0df5 Mon Sep 17 00:00:00 2001 From: Mike Robinson Date: Sun, 31 Aug 2014 15:50:34 +0100 Subject: [PATCH] Fix buffer overflow in JACK audio driver retroarch.c:flush_rewind_audio() can potentially send up to audio_data.rewind_buf of 2048 frames (4096 samples) to audio_flush(). rarch_resampler_process() can potentially multiply the number of frames by AUDIO_MAX_RATIO, to 32768 frames. audio/jack.c:write_buffer() allocates a buffer of only 2048 frames on the stack, which can overflow. This reliably happens when rewinding in slow motion. Multiply the JACK driver buffer by AUDIO_MAX_RATIO to prevent overflow. However, DSP can also adjust the number of frames without limit. There is no DSP_MAX_RATIO, so check the number of frames in audio/jack.c:write_buffer() and truncate if they will not fit the buffer. This will cause garbled audio, but in practice it is unlikely to occur (DSP plugins do not usually add frames, flush_rewind_audio() does not usually send the maximum possible number of frames). --- audio/jack.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/audio/jack.c b/audio/jack.c index 97e432b4df..26f5d239a4 100644 --- a/audio/jack.c +++ b/audio/jack.c @@ -214,14 +214,18 @@ static size_t write_buffer(jack_t *jd, const float *buf, size_t size) { int i; size_t j; - jack_default_audio_sample_t out_deinterleaved_buffer[2][AUDIO_CHUNK_SIZE_NONBLOCKING]; - - for (i = 0; i < 2; i++) - for (j = 0; j < FRAMES(size); j++) - out_deinterleaved_buffer[i][j] = buf[j * 2 + i]; + jack_default_audio_sample_t out_deinterleaved_buffer[2][AUDIO_CHUNK_SIZE_NONBLOCKING * AUDIO_MAX_RATIO]; size_t frames = FRAMES(size); + // Avoid buffer overflow if a DSP plugin generated a huge number of frames + if (frames > AUDIO_CHUNK_SIZE_NONBLOCKING * AUDIO_MAX_RATIO) + frames = AUDIO_CHUNK_SIZE_NONBLOCKING * AUDIO_MAX_RATIO; + + for (i = 0; i < 2; i++) + for (j = 0; j < frames; j++) + out_deinterleaved_buffer[i][j] = buf[j * 2 + i]; + size_t written = 0; while (written < frames) {