CVE-2023-1655: Heap-based Buffer Overflow (CWE-122)
value: Heap-based Buffer Overflow in GitHub repository gpac/gpac prior to 2.4.0.
CWE description: A heap overflow condition is a buffer overflow, where the buffer that can be overwritten is allocated in the heap portion of memory, generally meaning that the buffer was allocated using a routine such as malloc().
CVSS v3 base score: 7.8
Published: 2023-03-27T15:15Z
Repository: https://github.com/gpac/gpac
Language: C
Files changed: src/filters/reframe_rawpcm.c, src/utils/bitstream.c
Commit date: 2023-03-27 10:33:12 +0200
Commit message: fixed #2425

Diff: diff --git a/src/filters/reframe_rawpcm.c b/src/filters/reframe_rawpcm.c
index 0cce172c563d..75b8fbcf92ac 100644
--- a/src/filters/reframe_rawpcm.c
+++ b/src/filters/reframe_rawpcm.c
@@ -248,10 +248,11 @@ GF_Err pcmreframe_process(GF_Filter *filter)
 	data = (char *) gf_filter_pck_get_data(pck, &pck_size);
 	byte_offset = gf_filter_pck_get_byte_offset(pck);
 
 	if (ctx->probe_wave==1) {
 		Bool wav_ok = GF_TRUE;
+		Bool hdr_found = GF_FALSE;
 		GF_BitStream *bs;
 		if (ctx->probe_data) {
 			ctx->probe_data = gf_realloc(ctx->probe_data, ctx->probe_data_size+pck_size);
 			memcpy(ctx->probe_data + ctx->probe_data_size, data, pck_size);
 			ctx->probe_data_size += pck_size;
@@ -278,10 +279,11 @@ GF_Err pcmreframe_process(GF_Filter *filter)
 			if (type!=GF_4CC('f', 'm', 't', ' ')) {
 				gf_bs_skip_bytes(bs, csize);
 				continue;
 			}
 			//parse fmt
+			hdr_found = GF_TRUE;
 			u16 atype = gf_bs_read_u16_le(bs);
 			ctx->ch = gf_bs_read_u16_le(bs);
 			ctx->sr = gf_bs_read_u32_le(bs);
 			gf_bs_read_u32_le(bs); //byte rate
 			gf_bs_read_u16_le(bs); // block align
@@ -310,15 +312,17 @@ GF_Err pcmreframe_process(GF_Filter *filter)
 			if (!ctx->probe_data) {
 				ctx->probe_data = gf_malloc(pck_size);
 				memcpy(ctx->probe_data, data, pck_size);
 				ctx->probe_data_size = pck_size;
 			}
-			if (ctx->probe_data_size<=10000) {
-				gf_filter_pid_drop_packet(ctx->ipid);
-				return GF_OK;
+			if (!hdr_found) {
+				if (ctx->probe_data_size<=10000) {
+					gf_filter_pid_drop_packet(ctx->ipid);
+					return GF_OK;
+				}
+				GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[PCMReframe] Cannot find wave data chunk after %d bytes, aborting\n", ctx->probe_data_size));
 			}
-			GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[PCMReframe] Cannot find wave data chink afetr %d bytes, aborting\n", ctx->probe_data_size));
 			wav_ok = GF_FALSE;
 		}
 
 		ctx->wav_hdr_size = (u32) gf_bs_get_position(bs);
 
diff --git a/src/utils/bitstream.c b/src/utils/bitstream.c
index 926f85b3f59f..8e832257aae1 100644
--- a/src/utils/bitstream.c
+++ b/src/utils/bitstream.c
@@ -1264,10 +1264,14 @@ void gf_bs_skip_bytes(GF_BitStream *bs, u64 nbBytes)
 				gf_bs_read_u8(bs);
 				nbBytes--;
 			}
 		} else {
 			bs->position += nbBytes;
+			if (bs->position>bs->size) {
+				bs->position = bs->size;
+				bs->overflow_state = 1;
+			}
 		}
 		return;
 	}
 	/*for writing we must do it this way, otherwise pb in dynamic buffers*/
 	while (nbBytes) {

Vulnerable code: 			if (ctx->probe_data_size<=10000) {
				gf_filter_pid_drop_packet(ctx->ipid);
				return GF_OK;
			GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[PCMReframe] Cannot find wave data chink afetr %d bytes, aborting\n", ctx->probe_data_size));
Fixed code: 		Bool hdr_found = GF_FALSE;
			hdr_found = GF_TRUE;
			if (!hdr_found) {
				if (ctx->probe_data_size<=10000) {
					gf_filter_pid_drop_packet(ctx->ipid);
					return GF_OK;
				}
				GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[PCMReframe] Cannot find wave data chunk after %d bytes, aborting\n", ctx->probe_data_size));
			if (bs->position>bs->size) {
				bs->position = bs->size;
				bs->overflow_state = 1;
			}