Vulnerability: There is a integer overflow in function filter_core/filter_props.c:gf_props_assign_value in GPAC 1.0.1. In which, the arg const GF_PropertyValue *value,maybe value->value.data.size is a negative number. In result, memcpy in gf_props_assign_value failed.
Vulnerability ID: CVE-2021-29279
CWE: CWE-787
Severity score: 6.4
Project: https://github.com/gpac/gpac
Published: 2021-04-19
File: src/filters/reframe_flac.c
Commit message: fixed 1718
Commit author: jeanlf

Vulnerable version (before fix):
 typedef struct 	Bool is_playing; 	Bool is_file; 	Bool initial_play_done, file_loaded;  	Bool initialized; 	u32 sample_rate, nb_channels, bits_per_sample, block_size; GF_Err flac_dmx_process(GF_Filter *filter) 	u64 cts = GF_FILTER_NO_TS; 	FLACHeader hdr;  	//always reparse duration 	if (!ctx->duration.num) 		flac_dmx_check_dur(filter, ctx); GF_Err flac_dmx_process(GF_Filter *filter) 			gf_bs_reassign_buffer(ctx->bs, ctx->flac_buffer, size); 			u32 magic = gf_bs_read_u32(ctx->bs); 			if (magic != GF_4CC('f','L','a','C')) {  			} 			while (gf_bs_available(ctx->bs)) { 				Bool last = gf_bs_read_int(ctx->bs, 1); GF_Err flac_dmx_process(GF_Filter *filter) 				} 				if (last) break; 			} 			flac_dmx_check_pid(filter, ctx, ctx->flac_buffer+4, dsi_end-4); 			remain -= size; 			start += size;

Fixed version (after fix):
 typedef struct 	Bool is_playing; 	Bool is_file; 	Bool initial_play_done, file_loaded; 	Bool in_error;  	Bool initialized; 	u32 sample_rate, nb_channels, bits_per_sample, block_size; GF_Err flac_dmx_process(GF_Filter *filter) 	u64 cts = GF_FILTER_NO_TS; 	FLACHeader hdr;  	if (ctx->in_error) 		return GF_NON_COMPLIANT_BITSTREAM;  	//always reparse duration 	if (!ctx->duration.num) 		flac_dmx_check_dur(filter, ctx); GF_Err flac_dmx_process(GF_Filter *filter) 			gf_bs_reassign_buffer(ctx->bs, ctx->flac_buffer, size); 			u32 magic = gf_bs_read_u32(ctx->bs); 			if (magic != GF_4CC('f','L','a','C')) { 				GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[FLACDmx] invalid FLAC magic\n")); 				ctx->in_error = GF_TRUE; 				ctx->flac_buffer_size = 0; 				if (pck) 					gf_filter_pid_drop_packet(ctx->ipid); 				return GF_NON_COMPLIANT_BITSTREAM; 			} 			while (gf_bs_available(ctx->bs)) { 				Bool last = gf_bs_read_int(ctx->bs, 1); GF_Err flac_dmx_process(GF_Filter *filter) 				} 				if (last) break; 			} 			if (!dsi_end) { 				GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[FLACDmx] invalid FLAC header\n")); 				ctx->in_error = GF_TRUE; 				ctx->flac_buffer_size = 0; 				if (pck) 					gf_filter_pid_drop_packet(ctx->ipid); 				return GF_NON_COMPLIANT_BITSTREAM; 			} 			flac_dmx_check_pid(filter, ctx, ctx->flac_buffer+4, dsi_end-4); 			remain -= size; 			start += size;

Patch:
patch: @@ -59,6 +59,7 @@ typedef struct
 	Bool is_playing;
 	Bool is_file;
 	Bool initial_play_done, file_loaded;
+	Bool in_error;
 
 	Bool initialized;
 	u32 sample_rate, nb_channels, bits_per_sample, block_size;
@@ -388,6 +389,9 @@ GF_Err flac_dmx_process(GF_Filter *filter)
 	u64 cts = GF_FILTER_NO_TS;
 	FLACHeader hdr;
 
+	if (ctx->in_error)
+		return GF_NON_COMPLIANT_BITSTREAM;
+
 	//always reparse duration
 	if (!ctx->duration.num)
 		flac_dmx_check_dur(filter, ctx);
@@ -494,7 +498,12 @@ GF_Err flac_dmx_process(GF_Filter *filter)
 			gf_bs_reassign_buffer(ctx->bs, ctx->flac_buffer, size);
 			u32 magic = gf_bs_read_u32(ctx->bs);
 			if (magic != GF_4CC('f','L','a','C')) {
-
+				GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[FLACDmx] invalid FLAC magic\n"));
+				ctx->in_error = GF_TRUE;
+				ctx->flac_buffer_size = 0;
+				if (pck)
+					gf_filter_pid_drop_packet(ctx->ipid);
+				return GF_NON_COMPLIANT_BITSTREAM;
 			}
 			while (gf_bs_available(ctx->bs)) {
 				Bool last = gf_bs_read_int(ctx->bs, 1);
@@ -525,6 +534,14 @@ GF_Err flac_dmx_process(GF_Filter *filter)
 				}
 				if (last) break;
 			}
+			if (!dsi_end) {
+				GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[FLACDmx] invalid FLAC header\n"));
+				ctx->in_error = GF_TRUE;
+				ctx->flac_buffer_size = 0;
+				if (pck)
+					gf_filter_pid_drop_packet(ctx->ipid);
+				return GF_NON_COMPLIANT_BITSTREAM;
+			}
 			flac_dmx_check_pid(filter, ctx, ctx->flac_buffer+4, dsi_end-4);
 			remain -= size;
 			start += size;
path: src/filters/reframe_flac.c