Commit 86020073 authored by Ronald S. Bultje's avatar Ronald S. Bultje

xa_adpcm: limit filter to prevent xa_adpcm_table[] array bounds overruns.

Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
CC: libav-stable@libav.org
parent 1f8ff2b1
...@@ -265,8 +265,9 @@ static inline short adpcm_yamaha_expand_nibble(ADPCMChannelStatus *c, unsigned c ...@@ -265,8 +265,9 @@ static inline short adpcm_yamaha_expand_nibble(ADPCMChannelStatus *c, unsigned c
return c->predictor; return c->predictor;
} }
static void xa_decode(short *out, const unsigned char *in, static int xa_decode(AVCodecContext *avctx,
ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc) short *out, const unsigned char *in,
ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc)
{ {
int i, j; int i, j;
int shift,filter,f0,f1; int shift,filter,f0,f1;
...@@ -277,6 +278,12 @@ static void xa_decode(short *out, const unsigned char *in, ...@@ -277,6 +278,12 @@ static void xa_decode(short *out, const unsigned char *in,
shift = 12 - (in[4+i*2] & 15); shift = 12 - (in[4+i*2] & 15);
filter = in[4+i*2] >> 4; filter = in[4+i*2] >> 4;
if (filter > 4) {
av_log(avctx, AV_LOG_ERROR,
"Invalid XA-ADPCM filter %d (max. allowed is 4)\n",
filter);
return AVERROR_INVALIDDATA;
}
f0 = xa_adpcm_table[filter][0]; f0 = xa_adpcm_table[filter][0];
f1 = xa_adpcm_table[filter][1]; f1 = xa_adpcm_table[filter][1];
...@@ -304,7 +311,12 @@ static void xa_decode(short *out, const unsigned char *in, ...@@ -304,7 +311,12 @@ static void xa_decode(short *out, const unsigned char *in,
shift = 12 - (in[5+i*2] & 15); shift = 12 - (in[5+i*2] & 15);
filter = in[5+i*2] >> 4; filter = in[5+i*2] >> 4;
if (filter > 4) {
av_log(avctx, AV_LOG_ERROR,
"Invalid XA-ADPCM filter %d (max. allowed is 4)\n",
filter);
return AVERROR_INVALIDDATA;
}
f0 = xa_adpcm_table[filter][0]; f0 = xa_adpcm_table[filter][0];
f1 = xa_adpcm_table[filter][1]; f1 = xa_adpcm_table[filter][1];
...@@ -328,6 +340,8 @@ static void xa_decode(short *out, const unsigned char *in, ...@@ -328,6 +340,8 @@ static void xa_decode(short *out, const unsigned char *in,
left->sample2 = s_2; left->sample2 = s_2;
} }
} }
return 0;
} }
/** /**
...@@ -812,8 +826,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, ...@@ -812,8 +826,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
break; break;
case CODEC_ID_ADPCM_XA: case CODEC_ID_ADPCM_XA:
while (buf_size >= 128) { while (buf_size >= 128) {
xa_decode(samples, src, &c->status[0], &c->status[1], if ((ret = xa_decode(avctx, samples, src, &c->status[0],
avctx->channels); &c->status[1], avctx->channels)) < 0)
return ret;
src += 128; src += 128;
samples += 28 * 8; samples += 28 * 8;
buf_size -= 128; buf_size -= 128;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment