Vulnerability: The AV1_DuplicateConfig 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.
Vulnerability ID: CVE-2021-31262
CWE: CWE-476
Severity score: 2.9
Project: https://github.com/gpac/gpac
Published: 2021-04-19
File: src/isomedia/avc_ext.c
Commit message: fixed #1738
Commit author: jeanlf

Vulnerable version (before fix):
 static GF_Err gf_isom_check_mvc(GF_ISOFile *the_file, GF_TrackBox *trak, GF_MPEG 	return GF_OK; }  static GF_AV1Config* AV1_DuplicateConfig(GF_AV1Config const * const cfg) { 	u32 i = 0; 	GF_AV1Config *out = gf_malloc(sizeof(GF_AV1Config));  void AV1_RewriteESDescriptorEx(GF_MPEGVisualSampleEntryBox *av1, GF_MediaBox *md 		av1->emul_esd->decoderConfig->avgBitrate = btrt->avgBitrate; 		av1->emul_esd->decoderConfig->maxBitrate = btrt->maxBitrate; 	} 	if (av1->av1_config) { 		GF_AV1Config *av1_cfg = AV1_DuplicateConfig(av1->av1_config->config); 		if (av1_cfg) { 			gf_odf_av1_cfg_write(av1_cfg, &av1->emul_esd->decoderConfig->decoderSpecificInfo->data, &av1->emul_esd->decoderConfig->decoderSpecificInfo->dataLength); GF_AV1Config *gf_isom_av1_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 	trak = gf_isom_get_track_from_file(the_file, trackNumber); 	if (!trak || !trak->Media || !DescriptionIndex) return NULL; 	entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex - 1); 	if (!entry || !entry->av1_config) return NULL; 	return AV1_DuplicateConfig(entry->av1_config->config); } 

Fixed version (after fix):
 static GF_Err gf_isom_check_mvc(GF_ISOFile *the_file, GF_TrackBox *trak, GF_MPEG 	return GF_OK; }  static GF_AV1Config* AV1_DuplicateConfig(GF_AV1Config const * const cfg) { 	u32 i = 0; 	GF_AV1Config *out = gf_malloc(sizeof(GF_AV1Config));  void AV1_RewriteESDescriptorEx(GF_MPEGVisualSampleEntryBox *av1, GF_MediaBox *md 		av1->emul_esd->decoderConfig->avgBitrate = btrt->avgBitrate; 		av1->emul_esd->decoderConfig->maxBitrate = btrt->maxBitrate; 	} 	if (av1->av1_config && av1->av1_config->config) { 		GF_AV1Config *av1_cfg = AV1_DuplicateConfig(av1->av1_config->config); 		if (av1_cfg) { 			gf_odf_av1_cfg_write(av1_cfg, &av1->emul_esd->decoderConfig->decoderSpecificInfo->data, &av1->emul_esd->decoderConfig->decoderSpecificInfo->dataLength); GF_AV1Config *gf_isom_av1_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 	trak = gf_isom_get_track_from_file(the_file, trackNumber); 	if (!trak || !trak->Media || !DescriptionIndex) return NULL; 	entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex - 1); 	if (!entry || !entry->av1_config|| !entry->av1_config->config) return NULL; 	return AV1_DuplicateConfig(entry->av1_config->config); } 

Patch:
patch: @@ -1338,7 +1338,8 @@ static GF_Err gf_isom_check_mvc(GF_ISOFile *the_file, GF_TrackBox *trak, GF_MPEG
 	return GF_OK;
 }
 
-static GF_AV1Config* AV1_DuplicateConfig(GF_AV1Config const * const cfg) {
+static GF_AV1Config* AV1_DuplicateConfig(GF_AV1Config const * const cfg)
+{
 	u32 i = 0;
 	GF_AV1Config *out = gf_malloc(sizeof(GF_AV1Config));
 
@@ -1382,7 +1383,7 @@ void AV1_RewriteESDescriptorEx(GF_MPEGVisualSampleEntryBox *av1, GF_MediaBox *md
 		av1->emul_esd->decoderConfig->avgBitrate = btrt->avgBitrate;
 		av1->emul_esd->decoderConfig->maxBitrate = btrt->maxBitrate;
 	}
-	if (av1->av1_config) {
+	if (av1->av1_config && av1->av1_config->config) {
 		GF_AV1Config *av1_cfg = AV1_DuplicateConfig(av1->av1_config->config);
 		if (av1_cfg) {
 			gf_odf_av1_cfg_write(av1_cfg, &av1->emul_esd->decoderConfig->decoderSpecificInfo->data, &av1->emul_esd->decoderConfig->decoderSpecificInfo->dataLength);
@@ -2406,7 +2407,7 @@ GF_AV1Config *gf_isom_av1_config_get(GF_ISOFile *the_file, u32 trackNumber, u32
 	trak = gf_isom_get_track_from_file(the_file, trackNumber);
 	if (!trak || !trak->Media || !DescriptionIndex) return NULL;
 	entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->child_boxes, DescriptionIndex - 1);
-	if (!entry || !entry->av1_config) return NULL;
+	if (!entry || !entry->av1_config|| !entry->av1_config->config) return NULL;
 	return AV1_DuplicateConfig(entry->av1_config->config);
 }
path: src/isomedia/avc_ext.c