Vulnerability: Buffer overflow in the abst_box_read function in MP4Box in GPAC 1.0.1 allows attackers to cause a denial of service or execute arbitrary code via a crafted file.
Vulnerability ID: CVE-2021-31255
CWE: CWE-120
Severity score: 6.4
Project: https://github.com/gpac/gpac
Published: 2021-04-19
File: src/isomedia/box_code_adobe.c
Commit message: fixed #1733
Commit author: jeanlf

Vulnerable version (before fix):
 GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs) 	int i; 	u32 tmp_strsize; 	char *tmp_str; 	GF_Err e;  	ISOM_DECREASE_SIZE(ptr, 25) GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs) 		ISOM_DECREASE_SIZE(ptr, 1) 		tmp_str[i] = gf_bs_read_u8(bs); 		tmp_strsize--; 		if (!tmp_str[i]) 			break; 		i++; 	} 	if (i) { 		ptr->movie_identifier = gf_strdup(tmp_str); 	} GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs) 	ptr->server_entry_count = gf_bs_read_u8(bs); 	for (i=0; i<ptr->server_entry_count; i++) { 		int j=0; 		tmp_strsize=(u32)ptr->size; 		while (tmp_strsize) { 			ISOM_DECREASE_SIZE(ptr, 1) 			tmp_str[j] = gf_bs_read_u8(bs); 			tmp_strsize--; 			if (!tmp_str[j]) 				break; 			j++; 		} 		if (j) { 			gf_list_insert(ptr->server_entry_table, gf_strdup(tmp_str), i); 		} GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs) 	ptr->quality_entry_count = gf_bs_read_u8(bs); 	for (i=0; i<ptr->quality_entry_count; i++) { 		int j=0; 		tmp_strsize=(u32)ptr->size; 		while (tmp_strsize) { 			ISOM_DECREASE_SIZE(ptr, 1) 			tmp_str[j] = gf_bs_read_u8(bs); 			tmp_strsize--; 			if (!tmp_str[j]) 				break; 			j++; 		}  		if (j) { 			gf_list_insert(ptr->quality_entry_table, gf_strdup(tmp_str), i); 		} 	}  	i=0; 	tmp_strsize=(u32)ptr->size; 	while (tmp_strsize) { 		ISOM_DECREASE_SIZE(ptr, 1) 		tmp_str[i] = gf_bs_read_u8(bs); 		tmp_strsize--; 		if (!tmp_str[i]) 			break; 		i++; 	} 	if (i) { 		ptr->drm_data = gf_strdup(tmp_str); 	}  	i=0; 	tmp_strsize=(u32)ptr->size; 	while (tmp_strsize) { 		ISOM_DECREASE_SIZE(ptr, 1) 		tmp_str[i] = gf_bs_read_u8(bs); 		tmp_strsize--; 		if (!tmp_str[i]) 			break; 		i++; 	} 	if (i) { 		ptr->meta_data = gf_strdup(tmp_str); 	}

Fixed version (after fix):
 GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs) 	int i; 	u32 tmp_strsize; 	char *tmp_str; 	Bool zfound=GF_FALSE; 	GF_Err e;  	ISOM_DECREASE_SIZE(ptr, 25) GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs) 		ISOM_DECREASE_SIZE(ptr, 1) 		tmp_str[i] = gf_bs_read_u8(bs); 		tmp_strsize--; 		if (!tmp_str[i]) { 			zfound = GF_TRUE; 			break; 		} 		i++; 	} 	if (!zfound) 		return GF_ISOM_INVALID_FILE; 	if (i) { 		ptr->movie_identifier = gf_strdup(tmp_str); 	} GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs) 	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) 			tmp_str[j] = gf_bs_read_u8(bs); 			tmp_strsize--; 			if (!tmp_str[j]) { 				zfound = GF_TRUE; 				break; 			} 			j++; 		} 		if (!zfound) 			return GF_ISOM_INVALID_FILE; 		if (j) { 			gf_list_insert(ptr->server_entry_table, gf_strdup(tmp_str), i); 		} GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs) 	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) 			tmp_str[j] = gf_bs_read_u8(bs); 			tmp_strsize--; 			if (!tmp_str[j]) { 				zfound = GF_TRUE; 				break; 			} 			j++; 		}  		if (!zfound) 			return GF_ISOM_INVALID_FILE; 		if (j) { 			gf_list_insert(ptr->quality_entry_table, gf_strdup(tmp_str), i); 		} 	}  	i=0; 	tmp_strsize=(u32)ptr->size; 	zfound = GF_FALSE; 	while (tmp_strsize) { 		ISOM_DECREASE_SIZE(ptr, 1) 		tmp_str[i] = gf_bs_read_u8(bs); 		tmp_strsize--; 		if (!tmp_str[i]) { 			zfound = GF_TRUE; 			break; 		} 		i++; 	} 	if (!zfound) 		return GF_ISOM_INVALID_FILE; 	if (i) { 		ptr->drm_data = gf_strdup(tmp_str); 	}  	i=0; 	tmp_strsize=(u32)ptr->size; 	zfound = GF_FALSE; 	while (tmp_strsize) { 		ISOM_DECREASE_SIZE(ptr, 1) 		tmp_str[i] = gf_bs_read_u8(bs); 		tmp_strsize--; 		if (!tmp_str[i]) { 			zfound = GF_TRUE; 			break; 		} 		i++; 	} 	if (!zfound) 		return GF_ISOM_INVALID_FILE; 	if (i) { 		ptr->meta_data = gf_strdup(tmp_str); 	}

Patch:
patch: @@ -79,6 +79,7 @@ GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs)
 	int i;
 	u32 tmp_strsize;
 	char *tmp_str;
+	Bool zfound=GF_FALSE;
 	GF_Err e;
 
 	ISOM_DECREASE_SIZE(ptr, 25)
@@ -102,10 +103,14 @@ GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs)
 		ISOM_DECREASE_SIZE(ptr, 1)
 		tmp_str[i] = gf_bs_read_u8(bs);
 		tmp_strsize--;
-		if (!tmp_str[i])
+		if (!tmp_str[i]) {
+			zfound = GF_TRUE;
 			break;
+		}
 		i++;
 	}
+	if (!zfound)
+		return GF_ISOM_INVALID_FILE;
 	if (i) {
 		ptr->movie_identifier = gf_strdup(tmp_str);
 	}
@@ -114,15 +119,20 @@ GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs)
 	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)
 			tmp_str[j] = gf_bs_read_u8(bs);
 			tmp_strsize--;
-			if (!tmp_str[j])
+			if (!tmp_str[j]) {
+				zfound = GF_TRUE;
 				break;
+			}
 			j++;
 		}
+		if (!zfound)
+			return GF_ISOM_INVALID_FILE;
 		if (j) {
 			gf_list_insert(ptr->server_entry_table, gf_strdup(tmp_str), i);
 		}
@@ -132,45 +142,60 @@ GF_Err abst_box_read(GF_Box *s, GF_BitStream *bs)
 	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)
 			tmp_str[j] = gf_bs_read_u8(bs);
 			tmp_strsize--;
-			if (!tmp_str[j])
+			if (!tmp_str[j]) {
+				zfound = GF_TRUE;
 				break;
+			}
 			j++;
 		}
 
+		if (!zfound)
+			return GF_ISOM_INVALID_FILE;
 		if (j) {
 			gf_list_insert(ptr->quality_entry_table, gf_strdup(tmp_str), i);
 		}
 	}
 
 	i=0;
 	tmp_strsize=(u32)ptr->size;
+	zfound = GF_FALSE;
 	while (tmp_strsize) {
 		ISOM_DECREASE_SIZE(ptr, 1)
 		tmp_str[i] = gf_bs_read_u8(bs);
 		tmp_strsize--;
-		if (!tmp_str[i])
+		if (!tmp_str[i]) {
+			zfound = GF_TRUE;
 			break;
+		}
 		i++;
 	}
+	if (!zfound)
+		return GF_ISOM_INVALID_FILE;
 	if (i) {
 		ptr->drm_data = gf_strdup(tmp_str);
 	}
 
 	i=0;
 	tmp_strsize=(u32)ptr->size;
+	zfound = GF_FALSE;
 	while (tmp_strsize) {
 		ISOM_DECREASE_SIZE(ptr, 1)
 		tmp_str[i] = gf_bs_read_u8(bs);
 		tmp_strsize--;
-		if (!tmp_str[i])
+		if (!tmp_str[i]) {
+			zfound = GF_TRUE;
 			break;
+		}
 		i++;
 	}
+	if (!zfound)
+		return GF_ISOM_INVALID_FILE;
 	if (i) {
 		ptr->meta_data = gf_strdup(tmp_str);
 	}
path: src/isomedia/box_code_adobe.c