CVE-2021-32132 (published 2021-09-13T15:15Z)

The abst_box_size function in GPAC 1.0.1 allows attackers to cause a denial of service (NULL pointer dereference) via a crafted file in the MP4Box command.

Severity: MEDIUM
CVSS v2 base score: 4.3 (AV:N/AC:M/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 5.5, MEDIUM (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-476
cwe_name: NULL Pointer Dereference
description: The product dereferences a pointer that it expects to be valid but is NULL.
extended_description: 
            
            
            
         
         

Fix information:
repo_url: https://github.com/gpac/gpac
commit_details: repo_url: https://github.com/gpac/gpac
author: jeanlf
author_date: 2021-04-22 10:59:53+02:00
msg: fixed #1753
repository: repo_url: https://github.com/gpac/gpac
repo_name: gpac/gpac
description: GPAC Ultramedia OSS for Video Streaming & Next-Gen Multimedia Transcoding, Packaging & Delivery
repo_language: C
owner: gpac
file_changes: filename: isomedia_dev.h
change_type: ModificationType.MODIFY
diff: @@ -599,6 +599,13 @@ typedef struct
 		}\
 		__ptr->size -= bytes; \
 
+#define ISOM_DECREASE_SIZE_GOTO_EXIT(__ptr, bytes)	if (__ptr->size < (bytes) ) {\
+			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isom] not enough bytes in box %s: %d left, reading %d (file %s, line %d)\n", gf_4cc_to_str(__ptr->type), (u32) __ptr->size, (bytes), __FILE__, __LINE__ )); \
+			e = GF_ISOM_INVALID_FILE; \
+			goto exit;\
+		}\
+		__ptr->size -= bytes; \
+
 
 #define ISOM_DECREASE_SIZE_NO_ERR(__ptr, bytes)	if (__ptr->size < (bytes) ) {\
 			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isom] not enough bytes in box %s: %d left, reading %d (file %s, line %d), skipping box\n", gf_4cc_to_str(__ptr->type), (u32) __ptr->size, (bytes), __FILE__, __LINE__ )); \

programming_language: Lua
filename: box_code_adobe.c
change_type: ModificationType.MODIFY
diff: @@ -80,7 +80,7 @@ GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs)
 	u32 tmp_strsize;
 	char *tmp_str;
 	Bool zfound=GF_FALSE;
-	GF_Err e;
+	GF_Err e = GF_OK;
 
 	ISOM_DECREASE_SIZE(ptr, 25)
 	ptr->bootstrapinfo_version = gf_bs_read_u32(bs);
@@ -100,7 +100,7 @@ GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs)
 	memset(tmp_str, 0, sizeof(char)*tmp_strsize);
 
 	while (tmp_strsize) {
-		ISOM_DECREASE_SIZE(ptr, 1)
+		ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
 		tmp_str[i] = gf_bs_read_u8(bs);
 		tmp_strsize--;
 		if (!tmp_str[i]) {
@@ -109,20 +109,22 @@ GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs)
 		}
 		i++;
 	}
-	if (!zfound)
-		return GF_ISOM_INVALID_FILE;
+	if (!zfound) {
+		e = GF_ISOM_INVALID_FILE;
+		goto exit;
+	}
 	if (i) {
 		ptr->movie_identifier = gf_strdup(tmp_str);
 	}
 
-	ISOM_DECREASE_SIZE(ptr, 1)
+	ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
 	ptr->server_entry_count = gf_bs_read_u8(bs);
 	for (i=0; i<ptr->server_entry_count; i++) {
 		int j=0;
 		zfound = GF_FALSE;
 		tmp_strsize=(u32)ptr->size;
 		while (tmp_strsize) {
-			ISOM_DECREASE_SIZE(ptr, 1)
+			ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
 			tmp_str[j] = gf_bs_read_u8(bs);
 			tmp_strsize--;
 			if (!tmp_str[j]) {
@@ -131,21 +133,27 @@ GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs)
 			}
 			j++;
 		}
-		if (!zfound)
-			return GF_ISOM_INVALID_FILE;
+		if (!zfound) {
+			e = GF_ISOM_INVALID_FILE;
+			goto exit;
+		}
 		if (j) {
 			gf_list_insert(ptr->server_entry_table, gf_strdup(tmp_str), i);
 		}
 	}
+	if (ptr->server_entry_count != gf_list_count(ptr->server_entry_table)) {
+		e = GF_ISOM_INVALID_FILE;
+		goto exit;
+	}
 
-	ISOM_DECREASE_SIZE(ptr, 1)
+	ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
 	ptr->quality_entry_count = gf_bs_read_u8(bs);
 	for (i=0; i<ptr->quality_entry_count; i++) {
 		int j=0;
 		zfound = GF_FALSE;
 		tmp_strsize=(u32)ptr->size;
 		while (tmp_strsize) {
-			ISOM_DECREASE_SIZE(ptr, 1)
+			ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
 			tmp_str[j] = gf_bs_read_u8(bs);
 			tmp_strsize--;
 			if (!tmp_str[j]) {
@@ -155,18 +163,24 @@ GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs)
 			j++;
 		}
 
-		if (!zfound)
-			return GF_ISOM_INVALID_FILE;
+		if (!zfound) {
+			e = GF_ISOM_INVALID_FILE;
+			goto exit;
+		}
 		if (j) {
 			gf_list_insert(ptr->quality_entry_table, gf_strdup(tmp_str), i);
 		}
 	}
+	if (ptr->quality_entry_count != gf_list_count(ptr->quality_entry_table)) {
+		e = GF_ISOM_INVALID_FILE;
+		goto exit;
+	}
 
 	i=0;
 	tmp_strsize=(u32)ptr->size;
 	zfound = GF_FALSE;
 	while (tmp_strsize) {
-		ISOM_DECREASE_SIZE(ptr, 1)
+		ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
 		tmp_str[i] = gf_bs_read_u8(bs);
 		tmp_strsize--;
 		if (!tmp_str[i]) {
@@ -175,8 +189,11 @@ GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs)
 		}
 		i++;
 	}
-	if (!zfound)
-		return GF_ISOM_INVALID_FILE;
+	if (!zfound) {
+		e = GF_ISOM_INVALID_FILE;
+		goto exit;
+	}
+
 	if (i) {
 		ptr->drm_data = gf_strdup(tmp_str);
 	}
@@ -185,7 +202,7 @@ GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs)
 	tmp_strsize=(u32)ptr->size;
 	zfound = GF_FALSE;
 	while (tmp_strsize) {
-		ISOM_DECREASE_SIZE(ptr, 1)
+		ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
 		tmp_str[i] = gf_bs_read_u8(bs);
 		tmp_strsize--;
 		if (!tmp_str[i]) {
@@ -194,41 +211,50 @@ GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs)
 		}
 		i++;
 	}
-	if (!zfound)
-		return GF_ISOM_INVALID_FILE;
+	if (!zfound) {
+		e = GF_ISOM_INVALID_FILE;
+		goto exit;
+	}
+
 	if (i) {
 		ptr->meta_data = gf_strdup(tmp_str);
 	}
 
-	ISOM_DECREASE_SIZE(ptr, 1)
+	ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
 	ptr->segment_run_table_count = gf_bs_read_u8(bs);
 	for (i=0; i<ptr->segment_run_table_count; i++) {
 		GF_AdobeSegmentRunTableBox *asrt = NULL;
 		e = gf_isom_box_parse((GF_Box **)&asrt, bs);
 		if (e) {
 			if (asrt) gf_isom_box_del((GF_Box*)asrt);
-			gf_free(tmp_str);
-			return e;
+			goto exit;
 		}
 		gf_list_add(ptr->segment_run_table_entries, asrt);
 	}
+	if (ptr->segment_run_table_count != gf_list_count(ptr->segment_run_table_entries)) {
+		e = GF_ISOM_INVALID_FILE;
+		goto exit;
+	}
 
-	ISOM_DECREASE_SIZE(ptr, 1)
+	ISOM_DECREASE_SIZE_GOTO_EXIT(ptr, 1)
 	ptr->fragment_run_table_count = gf_bs_read_u8(bs);
 	for (i=0; i<ptr->fragment_run_table_count; i++) {
 		GF_AdobeFragmentRunTableBox *afrt = NULL;
 		e = gf_isom_box_parse((GF_Box **)&afrt, bs);
 		if (e) {
 			if (afrt) gf_isom_box_del((GF_Box*)afrt);
-			gf_free(tmp_str);
-			return e;
+			goto exit;
 		}
 		gf_list_add(ptr->fragment_run_table_entries, afrt);
 	}
+	if (ptr->fragment_run_table_count != gf_list_count(ptr->fragment_run_table_entries)) {
+		e = GF_ISOM_INVALID_FILE;
+		goto exit;
+	}
 
+exit:
 	gf_free(tmp_str);
-
-	return GF_OK;
+	return e;
 }
 
 GF_Box *abst_box_new()

programming_language: C