| From 3f7ed312614649e2695b54b398475d32be4f64f3 Mon Sep 17 00:00:00 2001 |
| From: Mans Rullgard <mans@mansr.com> |
| Date: Wed, 8 Nov 2017 00:29:14 +0000 |
| Subject: adpcm: fix stack overflow with >4 channels (CVE-2017-15372) |
| |
| --- |
| src/adpcm.c | 8 +++++++- |
| src/adpcm.h | 3 +++ |
| src/wav.c | 5 ++++- |
| 3 files changed, 14 insertions(+), 2 deletions(-) |
| |
| Index: sox/src/adpcm.c |
| =================================================================== |
| --- sox.orig/src/adpcm.c |
| +++ sox/src/adpcm.c |
| @@ -71,6 +71,11 @@ const short lsx_ms_adpcm_i_coef[7][2] = |
| { 392,-232} |
| }; |
| |
| +extern void *lsx_ms_adpcm_alloc(unsigned chans) |
| +{ |
| + return lsx_malloc(chans * sizeof(MsState_t)); |
| +} |
| + |
| static inline sox_sample_t AdpcmDecode(sox_sample_t c, MsState_t *state, |
| sox_sample_t sample1, sox_sample_t sample2) |
| { |
| @@ -102,6 +107,7 @@ static inline sox_sample_t AdpcmDecode(s |
| |
| /* lsx_ms_adpcm_block_expand_i() outputs interleaved samples into one output buffer */ |
| const char *lsx_ms_adpcm_block_expand_i( |
| + void *priv, |
| unsigned chans, /* total channels */ |
| int nCoef, |
| const short *coef, |
| @@ -113,7 +119,7 @@ const char *lsx_ms_adpcm_block_expand_i( |
| const unsigned char *ip; |
| unsigned ch; |
| const char *errmsg = NULL; |
| - MsState_t state[4]; /* One decompressor state for each channel */ |
| + MsState_t *state = priv; /* One decompressor state for each channel */ |
| |
| /* Read the four-byte header for each channel */ |
| ip = ibuff; |
| Index: sox/src/adpcm.h |
| =================================================================== |
| --- sox.orig/src/adpcm.h |
| +++ sox/src/adpcm.h |
| @@ -29,8 +29,11 @@ |
| /* default coef sets */ |
| extern const short lsx_ms_adpcm_i_coef[7][2]; |
| |
| +extern void *lsx_ms_adpcm_alloc(unsigned chans); |
| + |
| /* lsx_ms_adpcm_block_expand_i() outputs interleaved samples into one output buffer */ |
| extern const char *lsx_ms_adpcm_block_expand_i( |
| + void *priv, |
| unsigned chans, /* total channels */ |
| int nCoef, |
| const short *coef, |
| Index: sox/src/wav.c |
| =================================================================== |
| --- sox.orig/src/wav.c |
| +++ sox/src/wav.c |
| @@ -82,6 +82,7 @@ typedef struct { |
| /* following used by *ADPCM wav files */ |
| unsigned short nCoefs; /* ADPCM: number of coef sets */ |
| short *lsx_ms_adpcm_i_coefs; /* ADPCM: coef sets */ |
| + void *ms_adpcm_data; /* Private data of adpcm decoder */ |
| unsigned char *packet; /* Temporary buffer for packets */ |
| short *samples; /* interleaved samples buffer */ |
| short *samplePtr; /* Pointer to current sample */ |
| @@ -175,7 +176,7 @@ static unsigned short AdpcmReadBlock(so |
| } |
| } |
| |
| - errmsg = lsx_ms_adpcm_block_expand_i(ft->signal.channels, wav->nCoefs, wav->lsx_ms_adpcm_i_coefs, wav->packet, wav->samples, samplesThisBlock); |
| + errmsg = lsx_ms_adpcm_block_expand_i(wav->ms_adpcm_data, ft->signal.channels, wav->nCoefs, wav->lsx_ms_adpcm_i_coefs, wav->packet, wav->samples, samplesThisBlock); |
| |
| if (errmsg) |
| lsx_warn("%s", errmsg); |
| @@ -791,6 +792,7 @@ static int startread(sox_format_t * ft) |
| |
| /* nCoefs, lsx_ms_adpcm_i_coefs used by adpcm.c */ |
| wav->lsx_ms_adpcm_i_coefs = lsx_malloc(wav->nCoefs * 2 * sizeof(short)); |
| + wav->ms_adpcm_data = lsx_ms_adpcm_alloc(wChannels); |
| { |
| int i, errct=0; |
| for (i=0; len>=2 && i < 2*wav->nCoefs; i++) { |
| @@ -1216,6 +1218,7 @@ static int stopread(sox_format_t * ft) |
| free(wav->packet); |
| free(wav->samples); |
| free(wav->lsx_ms_adpcm_i_coefs); |
| + free(wav->ms_adpcm_data); |
| free(wav->comment); |
| wav->comment = NULL; |
| |