CVE-2021-31258: NULL Pointer Dereference (CWE-476)
value: The gf_isom_set_extraction_slc 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.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 5.5
Published: 2021-04-19T19:15Z
Repository: https://github.com/gpac/gpac
Language: C
Files changed: src/isomedia/isom_read.c, src/isomedia/isom_write.c, src/media_tools/isom_hinter.c
Commit date: 2021-03-12 11:56:53 +0100
Commit message: fixed #1706

Diff: diff --git a/src/isomedia/isom_read.c b/src/isomedia/isom_read.c
index f96f2e531ea..7f0079fbc8a 100644
--- a/src/isomedia/isom_read.c
+++ b/src/isomedia/isom_read.c
@@ -3901,10 +3901,11 @@ u32 gf_isom_guess_specification(GF_ISOFile *file)
 				break;
 			case GF_ISOM_SUBTYPE_MPEG4:
 			case GF_ISOM_SUBTYPE_MPEG4_CRYP:
 			{
 				GF_DecoderConfig *dcd = gf_isom_get_decoder_config(file, i+1, 1);
+				if (!dcd) break;
 				switch (dcd->streamType) {
 				case GF_STREAM_VISUAL:
 					if (dcd->objectTypeIndication==GF_CODECID_MPEG4_PART2) nb_m4v++;
 					else if ((dcd->objectTypeIndication==GF_CODECID_AVC) || (dcd->objectTypeIndication==GF_CODECID_SVC) || (dcd->objectTypeIndication==GF_CODECID_MVC)) nb_avc++;
 					else nb_v++;
diff --git a/src/isomedia/isom_write.c b/src/isomedia/isom_write.c
index 947dcdc638c..45de79f96ba 100644
--- a/src/isomedia/isom_write.c
+++ b/src/isomedia/isom_write.c
@@ -5350,29 +5350,36 @@ GF_Err gf_isom_set_extraction_slc(GF_ISOFile *the_file, u32 trackNumber, u32 Str
 {
 	GF_TrackBox *trak;
 	GF_SampleEntryBox *entry;
 	GF_Err e;
 	GF_SLConfig **slc;
+	GF_ESDBox *esds;
 
 	trak = gf_isom_get_track_from_file(the_file, trackNumber);
 	if (!trak) return GF_BAD_PARAM;
 
 	e = Media_GetSampleDesc(trak->Media, StreamDescriptionIndex, &entry, NULL);
 	if (e) return e;
 
 	//we must be sure we are not using a remote ESD
 	switch (entry->type) {
 	case GF_ISOM_BOX_TYPE_MP4S:
-		if (((GF_MPEGSampleEntryBox *)entry)->esd->desc->slConfig->predefined != SLPredef_MP4) return GF_BAD_PARAM;
+		esds = ((GF_MPEGSampleEntryBox *)entry)->esd;
+		if (!esds || !esds->desc || !esds->desc->slConfig || (esds->desc->slConfig->predefined != SLPredef_MP4))
+			return GF_ISOM_INVALID_FILE;
 		slc = & ((GF_MPEGSampleEntryBox *)entry)->slc;
 		break;
 	case GF_ISOM_BOX_TYPE_MP4A:
-		if (((GF_MPEGAudioSampleEntryBox *)entry)->esd->desc->slConfig->predefined != SLPredef_MP4) return GF_BAD_PARAM;
+		esds = ((GF_MPEGAudioSampleEntryBox *)entry)->esd;
+		if (!esds || !esds->desc || !esds->desc->slConfig || (esds->desc->slConfig->predefined != SLPredef_MP4))
+			return GF_ISOM_INVALID_FILE;
 		slc = & ((GF_MPEGAudioSampleEntryBox *)entry)->slc;
 		break;
 	case GF_ISOM_BOX_TYPE_MP4V:
-		if (((GF_MPEGVisualSampleEntryBox *)entry)->esd->desc->slConfig->predefined != SLPredef_MP4) return GF_BAD_PARAM;
+		esds = ((GF_MPEGVisualSampleEntryBox *)entry)->esd;
+		if (!esds || !esds->desc || !esds->desc->slConfig || (esds->desc->slConfig->predefined != SLPredef_MP4))
+			return GF_ISOM_INVALID_FILE;
 		slc = & ((GF_MPEGVisualSampleEntryBox *)entry)->slc;
 		break;
 	default:
 		return GF_BAD_PARAM;
 	}
diff --git a/src/media_tools/isom_hinter.c b/src/media_tools/isom_hinter.c
index 2d05934f6de..77b05141754 100644
--- a/src/media_tools/isom_hinter.c
+++ b/src/media_tools/isom_hinter.c
@@ -638,11 +638,15 @@ GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum,
 	gf_isom_rtp_set_timescale(file, tmp->HintTrack, descIndex, my_sl.timestampResolution);
 
 	if (hintType==GF_RTP_PAYT_MPEG4) {
 		tmp->rtp_p->slMap.CodecID = codecid;
 		/*set this SL for extraction.*/
-		gf_isom_set_extraction_slc(file, TrackNum, 1, &my_sl);
+		*e = gf_isom_set_extraction_slc(file, TrackNum, 1, &my_sl);
+		if (*e) {
+			gf_hinter_track_del(tmp);
+			return NULL;
+		}
 	}
 	tmp->bandwidth = bandwidth;
 
 	/*set interleaving*/
 	gf_isom_set_track_interleaving_group(file, TrackNum, InterleaveGroupID);

Vulnerable code: 		if (((GF_MPEGSampleEntryBox *)entry)->esd->desc->slConfig->predefined != SLPredef_MP4) return GF_BAD_PARAM;
		if (((GF_MPEGAudioSampleEntryBox *)entry)->esd->desc->slConfig->predefined != SLPredef_MP4) return GF_BAD_PARAM;
		if (((GF_MPEGVisualSampleEntryBox *)entry)->esd->desc->slConfig->predefined != SLPredef_MP4) return GF_BAD_PARAM;
		gf_isom_set_extraction_slc(file, TrackNum, 1, &my_sl);
Fixed code: 				if (!dcd) break;
	GF_ESDBox *esds;
		esds = ((GF_MPEGSampleEntryBox *)entry)->esd;
		if (!esds || !esds->desc || !esds->desc->slConfig || (esds->desc->slConfig->predefined != SLPredef_MP4))
			return GF_ISOM_INVALID_FILE;
		esds = ((GF_MPEGAudioSampleEntryBox *)entry)->esd;
		if (!esds || !esds->desc || !esds->desc->slConfig || (esds->desc->slConfig->predefined != SLPredef_MP4))
			return GF_ISOM_INVALID_FILE;
		esds = ((GF_MPEGVisualSampleEntryBox *)entry)->esd;
		if (!esds || !esds->desc || !esds->desc->slConfig || (esds->desc->slConfig->predefined != SLPredef_MP4))
			return GF_ISOM_INVALID_FILE;
		*e = gf_isom_set_extraction_slc(file, TrackNum, 1, &my_sl);
		if (*e) {
			gf_hinter_track_del(tmp);
			return NULL;
		}