Merged four commits: commit fcf0ba06ae12ccd7c67cee3c8d948df15f946b85 Author: Erik de Castro Lopo Date: Wed Nov 19 19:35:59 2014 -0800 src/libFACL/stream_decoder.c : Fail safely to avoid a heap overflow. A file provided by the reporters caused the stream decoder to write to un-allocated heap space resulting in a segfault. The solution is to error out (by returning false from read_residual_partitioned_rice_()) instead of trying to continue to decode. Fixes: CVE-2014-9028 Reported-by: Michele Spagnuolo, Google Security Team commit 5a365996d739bdf4711af51d9c2c71c8a5e14660 Author: Erik de Castro Lopo Date: Thu Nov 27 11:55:11 2014 +1100 src/libFLAC/stream_decoder.c : Fail safely to avoid a heap overflow. This fix is closely related to the fix for CVE-2014-9028. When that fix went public Miroslav Lichvar noticed a similar potential problem spot in the same function and was able to craft a file to trigger a heap write overflow. Reported-by : Miroslav Lichvar commit b4b2910bdca010808ccf2799f55562fa91f4347b Author: Erik de Castro Lopo Date: Wed Dec 10 18:54:16 2014 +1100 src/libFLAC/stream_decoder.c : Fix seek bug. Janne Hyvärinen reported a problem with seeking as a result of the fix for CVE-2014-9028. This is a different solution to the issue that should not adversely affect seeking. This version of the fix for the above CVE has been extensively fuzz tested using afl (http://lcamtuf.coredump.cx/afl/). Reported-by: Janne Hyvärinen commit fed0dfa1086296df0af41ca8f0c6430d5ac75c87 Author: Miroslav Lichvar Date: Mon Dec 15 15:46:12 2014 +0100 src/libFLAC/stream_decoder.c : Rework fix for seeking bug. To avoid crash caused by an unbound LPC decoding when predictor order is larger than blocksize, the sanity check needs to be moved to the subframe decoding functions. Signed-off-by: Erik de Castro Lopo diff -up flac-1.3.0/src/libFLAC/stream_decoder.c.cve-2014-9028 flac-1.3.0/src/libFLAC/stream_decoder.c --- flac-1.3.0/src/libFLAC/stream_decoder.c.cve-2014-9028 2015-03-27 16:59:10.898884915 +0100 +++ flac-1.3.0/src/libFLAC/stream_decoder.c 2015-03-27 17:00:34.879125031 +0100 @@ -2550,6 +2550,11 @@ FLAC__bool read_subframe_fixed_(FLAC__St case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) return false; /* read_callback_ sets the state for us */ + if(decoder->private_->frame.header.blocksize >> u32 < order) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } subframe->entropy_coding_method.data.partitioned_rice.order = u32; subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel]; break; @@ -2629,6 +2634,11 @@ FLAC__bool read_subframe_lpc_(FLAC__Stre case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &u32, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) return false; /* read_callback_ sets the state for us */ + if(decoder->private_->frame.header.blocksize >> u32 < order) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } subframe->entropy_coding_method.data.partitioned_rice.order = u32; subframe->entropy_coding_method.data.partitioned_rice.contents = &decoder->private_->partitioned_rice_contents[channel]; break; @@ -2704,21 +2714,8 @@ FLAC__bool read_residual_partitioned_ric const unsigned plen = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; const unsigned pesc = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; - /* sanity checks */ - if(partition_order == 0) { - if(decoder->private_->frame.header.blocksize < predictor_order) { - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - } - else { - if(partition_samples < predictor_order) { - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } - } + /* invalid predictor and partition orders mush be handled in the callers */ + FLAC__ASSERT(partition_order > 0? partition_samples >= predictor_order : decoder->private_->frame.header.blocksize >= predictor_order); if(!FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, flac_max(6u, partition_order))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;