1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
Description: more fixes for FLAC error handling
fixes CVE-2017-7742, CVE-2017-7741, CVE-2017-7585
Author: Eric de Castro Lopo
Origin: upstream
Applied-Upstream: https://github.com/erikd/libsndfile/commit/60b234301adf258786d8b90be5c1d437fc8799e0
Last-Update: 2017-05-28
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- libsndfile.orig/src/flac.c
+++ libsndfile/src/flac.c
@@ -68,9 +68,9 @@
unsigned bufferpos ;
const FLAC__Frame *frame ;
- FLAC__bool bufferbackup ;
unsigned compression ;
+
} FLAC_PRIVATE ;
typedef struct
@@ -187,10 +187,9 @@
if (pflac->ptr == NULL)
{ /*
- ** Not sure why this code is here and not elsewhere.
- ** Removing it causes valgrind errors.
+ ** This pointer is reset to NULL each time the current frame has been
+ ** decoded. Somehow its used during encoding and decoding.
*/
- pflac->bufferbackup = SF_TRUE ;
for (i = 0 ; i < channels ; i++)
{
if (pflac->rbuffer [i] == NULL)
@@ -206,6 +205,11 @@
len = SF_MIN (pflac->len, frame->header.blocksize) ;
+ if (pflac->remain % channels != 0)
+ { psf_log_printf (psf, "Error: pflac->remain %u channels %u\n", pflac->remain, channels) ;
+ return 0 ;
+ } ;
+
switch (pflac->pcmtype)
{ case PFLAC_PCM_SHORT :
{ short *retpcm = (short*) pflac->ptr ;
@@ -381,7 +385,6 @@
pflac->frame = frame ;
pflac->bufferpos = 0 ;
- pflac->bufferbackup = SF_FALSE ;
pflac->wbuffer = buffer ;
flac_buffer_copy (psf) ;
@@ -906,11 +909,19 @@
static unsigned
flac_read_loop (SF_PRIVATE *psf, unsigned len)
{ FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
+ FLAC__StreamDecoderState state ;
pflac->pos = 0 ;
pflac->len = len ;
pflac->remain = len ;
+ state = FLAC__stream_decoder_get_state (pflac->fsd) ;
+ if (state > FLAC__STREAM_DECODER_END_OF_STREAM)
+ { psf_log_printf (psf, "FLAC__stream_decoder_get_state returned %s\n", FLAC__StreamDecoderStateString [state]) ;
+ /* Current frame is busted, so NULL the pointer. */
+ pflac->frame = NULL ;
+ } ;
+
/* First copy data that has already been decoded and buffered. */
if (pflac->frame != NULL && pflac->bufferpos < pflac->frame->header.blocksize)
flac_buffer_copy (psf) ;
@@ -919,8 +930,13 @@
while (pflac->pos < pflac->len)
{ if (FLAC__stream_decoder_process_single (pflac->fsd) == 0)
break ;
- if (FLAC__stream_decoder_get_state (pflac->fsd) >= FLAC__STREAM_DECODER_END_OF_STREAM)
+ state = FLAC__stream_decoder_get_state (pflac->fsd) ;
+ if (state >= FLAC__STREAM_DECODER_END_OF_STREAM)
+ { psf_log_printf (psf, "FLAC__stream_decoder_get_state returned %s\n", FLAC__StreamDecoderStateString [state]) ;
+ /* Current frame is busted, so NULL the pointer. */
+ pflac->frame = NULL ;
break ;
+ } ;
} ;
pflac->ptr = NULL ;
|