CVE-2022-4202: Numeric Errors (CWE-189)
value: A vulnerability, which was classified as problematic, was found in GPAC 2.1-DEV-rev490-g68064e101-master. Affected is the function lsr_translate_coords of the file laser/lsr_dec.c. The manipulation leads to integer overflow. It is possible to launch the attack remotely. The exploit has been disclosed to the public and may be used. The name of the patch is b3d821c4ae9ba62b3a194d9dcb5e99f17bd56908. It is recommended to apply a patch to fix this issue. VDB-214518 is the identifier assigned to this vulnerability.
CWE description: Weaknesses in this category are related to improper calculation or conversion of numbers.
CVSS v3 base score: 8.8
Published: 2022-11-29T09:15Z
Repository: https://github.com/gpac/gpac
Language: C
Files changed: src/laser/lsr_dec.c
Commit date: 2022-12-12 09:35:12 +0100
Commit message: fixed #2333

Diff: diff --git a/src/laser/lsr_dec.c b/src/laser/lsr_dec.c
index 488babb1045a..283092f2a150 100644
--- a/src/laser/lsr_dec.c
+++ b/src/laser/lsr_dec.c
@@ -298,15 +298,25 @@ static void lsr_read_extension(GF_LASeRCodec *lsr, const char *name)
 #endif
 }
 
 static void lsr_read_extend_class(GF_LASeRCodec *lsr, char **out_data, u32 *out_len, const char *name)
 {
-	u32 len;
+	u32 len, blen;
 	GF_LSR_READ_INT(lsr, len, lsr->info->cfg.extensionIDBits, "reserved");
 	len = lsr_read_vluimsbf5(lsr, "len");
-//	while (len) gf_bs_read_int(lsr->bs, 1);
-	gf_bs_read_long_int(lsr->bs, len);
+	while (len && !gf_bs_is_align(lsr->bs)) {
+		gf_bs_read_int(lsr->bs, len);
+		len--;
+	}
+	blen = len / 8;
+	gf_bs_skip_bytes(lsr->bs, blen);
+	len -= blen*8;
+
+	while (len) {
+		gf_bs_read_int(lsr->bs, 1);
+		len--;
+	}
 	if (out_data) *out_data = NULL;
 	if (out_len) *out_len = 0;
 }
 
 static void lsr_read_private_element_container(GF_LASeRCodec *lsr)
@@ -837,36 +847,37 @@ static void lsr_read_id(GF_LASeRCodec *lsr, GF_Node *n)
 }
 
 static Fixed lsr_translate_coords(GF_LASeRCodec *lsr, u32 val, u32 nb_bits)
 {
 	if (!nb_bits) return 0;
-	
+	if (nb_bits>=32) return 0;
+
 #ifdef GPAC_FIXED_POINT
 	if (val >> (nb_bits-1) ) {
-		s32 neg = (s32) val - (1<<nb_bits);
+		s64 neg = (s64) val - (0x00000001UL << nb_bits);
 		if (neg < -FIX_ONE / 2)
 			return 2 * gf_divfix(INT2FIX(neg/2), lsr->res_factor);
 		return gf_divfix(INT2FIX(neg), lsr->res_factor);
 	} else {
 		if (val > FIX_ONE / 2)
 			return 2 * gf_divfix(INT2FIX(val/2), lsr->res_factor);
 		return gf_divfix(INT2FIX(val), lsr->res_factor);
 	}
 #else
 	if (val >> (nb_bits-1) ) {
-		s32 neg = (s32) val - (1<<nb_bits);
-		return gf_divfix(INT2FIX(neg), lsr->res_factor);
+		s64 neg = (s64) val - (0x00000001UL << nb_bits);
+		return ((Fixed)neg) / lsr->res_factor;
 	} else {
-		return gf_divfix(INT2FIX(val), lsr->res_factor);
+		return ((Fixed)val) / lsr->res_factor;
 	}
 #endif
 }
 
 static Fixed lsr_translate_scale(GF_LASeRCodec *lsr, u32 val)
 {
 	if (val >> (lsr->coord_bits-1) ) {
-		s32 v = val - (1<<lsr->coord_bits);
+		s64 v = val - (0x00000001UL << lsr->coord_bits);
 		return INT2FIX(v) / 256 ;
 	} else {
 		return INT2FIX(val) / 256;
 	}
 }

Vulnerable code: 	u32 len;
//	while (len) gf_bs_read_int(lsr->bs, 1);
	gf_bs_read_long_int(lsr->bs, len);
	
		s32 neg = (s32) val - (1<<nb_bits);
		s32 neg = (s32) val - (1<<nb_bits);
		return gf_divfix(INT2FIX(neg), lsr->res_factor);
		return gf_divfix(INT2FIX(val), lsr->res_factor);
		s32 v = val - (1<<lsr->coord_bits);
Fixed code: 	u32 len, blen;
	while (len && !gf_bs_is_align(lsr->bs)) {
		gf_bs_read_int(lsr->bs, len);
		len--;
	}
	blen = len / 8;
	gf_bs_skip_bytes(lsr->bs, blen);
	len -= blen*8;

	while (len) {
		gf_bs_read_int(lsr->bs, 1);
		len--;
	}
	if (nb_bits>=32) return 0;

		s64 neg = (s64) val - (0x00000001UL << nb_bits);
		s64 neg = (s64) val - (0x00000001UL << nb_bits);
		return ((Fixed)neg) / lsr->res_factor;
		return ((Fixed)val) / lsr->res_factor;
		s64 v = val - (0x00000001UL << lsr->coord_bits);