CVE-2022-2453 (C, published 2022-07-19T14:15Z)
Description: value: Use After Free in GitHub repository gpac/gpac prior to 2.1-DEV.
Severity: nan (CVSS v3 base score: 7.8)
Weakness: CWE-416 \u2014 Use After Free
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.
Repository: https://github.com/gpac/gpac
Files changed:
src/bifs/field_decode.c
Commit message: fixed #2212


Vulnerable code:
	} 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);
						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 {
						if (e) return e;
				/*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;
		/*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) {
			} 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);
			}
	return GF_OK;

Fixed code:
		return GF_OK;
	}
	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) {
						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)goto exit;
			}
		} else {
			e = codec->LastError ? codec->LastError : GF_NON_COMPLIANT_BITSTREAM;
			goto exit;
	}

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) {
		} 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);

	return e;