CVE-2021-40568: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow') (CWE-120)
value: A buffer overflow vulnerability exists in Gpac through 1.0.1 via a malformed MP4 file in the svc_parse_slice function in av_parsers.c, which allows attackers to cause a denial of service, even code execution and escalation of privileges.
CWE description: The product copies an input buffer to an output buffer without verifying that the size of the input buffer is less than the size of the output buffer, leading to a buffer overflow.
CVSS v3 base score: 7.8
Published: 2022-01-13T18:15Z
Repository: https://github.com/gpac/gpac
Language: C
Files changed: src/media_tools/av_parsers.c
Commit date: 2021-08-30 17:20:00 +0200
Commit message: fixed #1900

Diff: diff --git a/src/media_tools/av_parsers.c b/src/media_tools/av_parsers.c
index 2a819da12c94..96d279742021 100644
--- a/src/media_tools/av_parsers.c
+++ b/src/media_tools/av_parsers.c
@@ -4688,24 +4688,27 @@ u32 gf_bs_read_ue_log_idx3(GF_BitStream *bs, const char *fname, s32 idx1, s32 id
 	u32 val=0, code;
 	s32 nb_lead = -1;
 	u32 bits = 0;
 	for (code=0; !code; nb_lead++) {
 		if (nb_lead>=32) {
-			//gf_bs_read_int keeps returning 0 on EOS, so if no more bits available, rbsp was truncated otherwise code is broken in rbsp)
-			//we only test once nb_lead>=32 to avoid testing at each bit read
-			if (!gf_bs_available(bs)) {
-				GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[Core] exp-golomb read failed, not enough bits in bitstream !\n"));
-			} else {
-				GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[Core] corrupted exp-golomb code, %d leading zeros, max 31 allowed !\n", nb_lead));
-			}
-			return 0;
+			break;
 		}
-
 		code = gf_bs_read_int(bs, 1);
 		bits++;
 	}
 
+	if (nb_lead>=32) {
+		//gf_bs_read_int keeps returning 0 on EOS, so if no more bits available, rbsp was truncated otherwise code is broken in rbsp)
+		//we only test once nb_lead>=32 to avoid testing at each bit read
+		if (!gf_bs_available(bs)) {
+			GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[Core] exp-golomb read failed, not enough bits in bitstream !\n"));
+		} else {
+			GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[Core] corrupted exp-golomb code, %d leading zeros, max 31 allowed !\n", nb_lead));
+		}
+		return 0;
+	}
+
 	if (nb_lead) {
 		u32 leads=1;
 		val = gf_bs_read_int(bs, nb_lead);
 		leads <<= nb_lead;
 		leads -= 1;
@@ -5783,11 +5786,11 @@ static s32 svc_parse_slice(GF_BitStream *bs, AVCState *avc, AVCSliceInfo *si)
 	gf_bs_read_ue_log(bs, "first_mb_in_slice");
 	si->slice_type = gf_bs_read_ue_log(bs, "slice_type");
 	if (si->slice_type > 9) return -1;
 
 	pps_id = gf_bs_read_ue_log(bs, "pps_id");
-	if (pps_id > 255)
+	if ((pps_id<0) || (pps_id > 255))
 		return -1;
 	si->pps = &avc->pps[pps_id];
 	si->pps->id = pps_id;
 	if (!si->pps->slice_group_count)
 		return -2;

Vulnerable code: 			//gf_bs_read_int keeps returning 0 on EOS, so if no more bits available, rbsp was truncated otherwise code is broken in rbsp)
			//we only test once nb_lead>=32 to avoid testing at each bit read
			if (!gf_bs_available(bs)) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[Core] exp-golomb read failed, not enough bits in bitstream !\n"));
			} else {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[Core] corrupted exp-golomb code, %d leading zeros, max 31 allowed !\n", nb_lead));
			}
			return 0;

	if (pps_id > 255)
Fixed code: 			break;
	if (nb_lead>=32) {
		//gf_bs_read_int keeps returning 0 on EOS, so if no more bits available, rbsp was truncated otherwise code is broken in rbsp)
		//we only test once nb_lead>=32 to avoid testing at each bit read
		if (!gf_bs_available(bs)) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[Core] exp-golomb read failed, not enough bits in bitstream !\n"));
		} else {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[Core] corrupted exp-golomb code, %d leading zeros, max 31 allowed !\n", nb_lead));
		}
		return 0;
	}

	if ((pps_id<0) || (pps_id > 255))