CVE-2022-2453 (published 2022-07-19T14:15Z)

Use After Free in GitHub repository gpac/gpac prior to 2.1-DEV.

CVSS v3 base score: 7.8, HIGH (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-416
cwe_name: Use After Free
description: The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory "belongs" to the code that operates on the new pointer.
extended_description: 
             
             
             
			 
             
             
         
         

Fix information:
repo_url: https://github.com/gpac/gpac
commit_details: repo_url: https://github.com/gpac/gpac
author: jeanlf
author_date: 2022-07-12 17:57:03+02:00
msg: fixed #2212
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: field_decode.c
change_type: ModificationType.MODIFY
diff: @@ -427,64 +427,71 @@ GF_Err BD_DecMFFieldVec(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node,
 			e = gf_bifs_dec_sf_field(codec, bs, node, &sffield, GF_FALSE);
 			if (e) return e;
 		}
-	} else {
-		last = NULL;
-		for (i=0; i<nbFields; i++) {
-			GF_Node *new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);
-			if (new_node) {
-				e = gf_node_register(new_node, is_mem_com ? NULL : node);
-				if (e) return e;
-
-				if (node) {
-					/*special case for QP, register as the current QP*/
-					if (gf_node_get_tag(new_node) == TAG_MPEG4_QuantizationParameter) {
-						qp_local = ((M_QuantizationParameter *)new_node)->isLocal;
-						/*we have a QP in the same scope, remove previous
-						NB: we assume this is the right behavior, the spec doesn't say
-						whether QP is cumulative or not*/
-						if (qp_on) gf_bifs_dec_qp_remove(codec, GF_FALSE);
+		return GF_OK;
+	}
 
-						e = gf_bifs_dec_qp_set(codec, new_node);
-						if (e) return e;
-						qp_on = 1;
-						if (qp_local) qp_local = 2;
-						if (codec->force_keep_qp) {
-							e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
-							if (e) return e;
-						} else {
-							gf_node_register(new_node, NULL);
-							gf_node_unregister(new_node, node);
-						}
-					} else {
+	e = GF_OK;
+	last = NULL;
+	for (i=0; i<nbFields; i++) {
+		GF_Node *new_node = gf_bifs_dec_node(codec, bs, field->NDTtype);
+		if (new_node) {
+			e = gf_node_register(new_node, is_mem_com ? NULL : node);
+			if (e) goto exit;
+
+			if (node) {
+				/*special case for QP, register as the current QP*/
+				if (gf_node_get_tag(new_node) == TAG_MPEG4_QuantizationParameter) {
+					qp_local = ((M_QuantizationParameter *)new_node)->isLocal;
+					/*we have a QP in the same scope, remove previous
+					NB: we assume this is the right behavior, the spec doesn't say
+					whether QP is cumulative or not*/
+					if (qp_on) gf_bifs_dec_qp_remove(codec, GF_FALSE);
+
+					e = gf_bifs_dec_qp_set(codec, new_node);
+					if (e) goto exit;
+					qp_on = 1;
+					if (qp_local) qp_local = 2;
+					if (codec->force_keep_qp) {
 						e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
-						if (e) return e;
+						if (e) goto exit;
+					} else {
+						gf_node_register(new_node, NULL);
+						gf_node_unregister(new_node, node);
 					}
+				} else {
+					e = gf_node_list_add_child_last(field->far_ptr, new_node, &last);
+					if (e) goto exit;
 				}
-				/*proto coding*/
-				else if (codec->pCurrentProto) {
-					/*TO DO: what happens if this is a QP node on the interface ?*/
-					e = gf_node_list_add_child_last( (GF_ChildNodeItem **)field->far_ptr, new_node, &last);
-					if (e) return e;
-				}
-			} else {
-				return codec->LastError ? codec->LastError : GF_NON_COMPLIANT_BITSTREAM;
 			}
+			/*proto coding*/
+			else if (codec->pCurrentProto) {
+				/*TO DO: what happens if this is a QP node on the interface ?*/
+				e = gf_node_list_add_child_last( (GF_ChildNodeItem **)field->far_ptr, new_node, &last);
+				if (e)goto exit;
+			}
+		} else {
+			e = codec->LastError ? codec->LastError : GF_NON_COMPLIANT_BITSTREAM;
+			goto exit;
 		}
-		/*according to the spec, the QP applies to the current node itself, not just children.
-		If IsLocal is TRUE remove the node*/
-		if (qp_on && qp_local) {
-			if (qp_local == 2) {
+	}
+
+exit:
+
+	/*according to the spec, the QP applies to the current node itself, not just children.
+	If IsLocal is TRUE remove the node*/
+	if (qp_on && qp_local) {
+		if (qp_local == 2) {
 //				qp_local = 1;
-			} else {
-				//ask to get rid of QP and reactivate if we had a QP when entering the node
-				gf_bifs_dec_qp_remove(codec, initial_qp);
+		} else {
+			//ask to get rid of QP and reactivate if we had a QP when entering the node
+			gf_bifs_dec_qp_remove(codec, initial_qp);
 //				qp_local = 0;
-			}
 		}
 	}
+
 	/*finally delete the QP if any (local or not) as we get out of this node*/
 	if (qp_on) gf_bifs_dec_qp_remove(codec, GF_TRUE);
-	return GF_OK;
+	return e;
 }
 
 

programming_language: C