Blame SOURCES/flac-1.3.0-cve-2014-9028.patch

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