CVE-2023-5377 (published 2023-10-04T10:15Z)

Out-of-bounds Read in GitHub repository gpac/gpac prior to v2.2.2-DEV.

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

Weakness information:
cwe_id: CWE-125
cwe_name: Out-of-bounds Read
description: The product reads data past the end, or before the beginning, of the intended buffer.
extended_description: 
            
            
             
			 
         
         

Fix information:
repo_url: https://github.com/gpac/gpac
commit_details: repo_url: https://github.com/gpac/gpac
author: jeanlf
author_date: 2023-10-04 11:49:06+02:00
msg: fixed #2606
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: isomedia.h
change_type: ModificationType.MODIFY
diff: @@ -1465,9 +1465,23 @@ typedef struct
 {
 	/*! stream structure flags, 1: has channel layout, 2: has objects*/
 	u8 stream_structure;
+	/*!  order of formats in the stream : 0 unknown, 1: Channels, possibly followed by Objects, 2 Objects, possibly followed by Channels*/
+	u8 format_ordering;
+	/*! combined channel count of the channel layout and the object count*/
+	u8 base_channel_count;
 
 	/*! defined CICP channel layout*/
 	u8 definedLayout;
+	/*! indicates where the ordering of the audio channels for the definedLayout are specified
+	0: as listed for the ChannelConfigurations in ISO/IEC 23091-3
+	1: Default order of audio codec specification
+	2: Channel ordering #2 of audio codec specification
+	3: Channel ordering #3 of audio codec specification
+	4: Channel ordering #4 of audio codec specification
+	*/
+	u8 channel_order_definition;
+	/*! indicates if omittedChannelsMap is present*/
+	u8 omitted_channels_present;
 
 	/*! number of channels*/
 	u32 channels_count;

programming_language: JavaScript
filename: box_code_base.c
change_type: ModificationType.MODIFY
diff: @@ -12676,7 +12676,14 @@ GF_Err chnl_box_read(GF_Box *s,GF_BitStream *bs)
 	GF_ChannelLayoutBox *ptr = (GF_ChannelLayoutBox *) s;
 
 	ISOM_DECREASE_SIZE(s, 1)
-	ptr->layout.stream_structure = gf_bs_read_u8(bs);
+	if (ptr->version==0) {
+		ptr->layout.stream_structure = gf_bs_read_u8(bs);
+	} else {
+		ptr->layout.stream_structure = gf_bs_read_int(bs, 4);
+		ptr->layout.format_ordering = gf_bs_read_int(bs, 4);
+		ISOM_DECREASE_SIZE(s, 1)
+		ptr->layout.base_channel_count = gf_bs_read_u8(bs);
+	}
 	if (ptr->layout.stream_structure & 1) {
 		ISOM_DECREASE_SIZE(s, 1)
 		ptr->layout.definedLayout = gf_bs_read_u8(bs);
@@ -12684,7 +12691,14 @@ GF_Err chnl_box_read(GF_Box *s,GF_BitStream *bs)
 			u32 remain = (u32) ptr->size;
 			if (ptr->layout.stream_structure & 2) remain--;
 			ptr->layout.channels_count = 0;
+			u32 nb_channels = 0;
+			if (ptr->version) {
+				ISOM_DECREASE_SIZE(s, 1)
+				nb_channels = gf_bs_read_u8(bs);
+			}
 			while (remain) {
+				if (ptr->layout.channels_count==64) return GF_ISOM_INVALID_FILE;
+
 				ISOM_DECREASE_SIZE(s, 1)
 				ptr->layout.layouts[ptr->layout.channels_count].position = gf_bs_read_u8(bs);
 				remain--;
@@ -12694,13 +12708,31 @@ GF_Err chnl_box_read(GF_Box *s,GF_BitStream *bs)
 					ptr->layout.layouts[ptr->layout.channels_count].elevation = gf_bs_read_int(bs, 8);
 					remain-=3;
 				}
+				ptr->layout.channels_count++;
+				if (ptr->version) {
+					nb_channels--;
+					if (!nb_channels) break;
+				}
 			}
 		} else {
-			ISOM_DECREASE_SIZE(s, 8)
-			ptr->layout.omittedChannelsMap = gf_bs_read_u64(bs);
+			if (ptr->version==0) {
+				ISOM_DECREASE_SIZE(s, 8)
+				ptr->layout.omittedChannelsMap = gf_bs_read_u64(bs);
+				ptr->layout.omitted_channels_present = 1;
+				ptr->layout.channel_order_definition = 0;
+			} else {
+				ISOM_DECREASE_SIZE(s, 1)
+				gf_bs_read_int(bs, 4);
+				ptr->layout.channel_order_definition = gf_bs_read_int(bs, 3);
+				ptr->layout.omitted_channels_present = gf_bs_read_int(bs, 1);
+				if (ptr->layout.omitted_channels_present) {
+					ISOM_DECREASE_SIZE(s, 8)
+					ptr->layout.omittedChannelsMap = gf_bs_read_u64(bs);
+				}
+			}
 		}
 	}
-	if (ptr->layout.stream_structure & 2) {
+	if ((ptr->version==0) && (ptr->layout.stream_structure & 2)) {
 		ISOM_DECREASE_SIZE(s, 1)
 		ptr->layout.object_count = gf_bs_read_u8(bs);
 	}
@@ -12724,10 +12756,20 @@ GF_Err chnl_box_write(GF_Box *s, GF_BitStream *bs)
 	if (e) return e;
 
 	gf_bs_write_u8(bs, ptr->layout.stream_structure);
+	if (ptr->version==0) {
+		gf_bs_write_u8(bs, ptr->layout.stream_structure);
+	} else {
+		gf_bs_write_int(bs, ptr->layout.stream_structure, 4);
+		gf_bs_write_int(bs, ptr->layout.format_ordering, 4);
+		gf_bs_write_u8(bs, ptr->layout.base_channel_count);
+	}
 	if (ptr->layout.stream_structure & 1) {
 		gf_bs_write_u8(bs, ptr->layout.definedLayout);
 		if (ptr->layout.definedLayout==0) {
 			u32 i;
+			if (ptr->version==1) {
+				gf_bs_write_u8(bs, ptr->layout.channels_count);
+			}
 			for (i=0; i<ptr->layout.channels_count; i++) {
 				gf_bs_write_u8(bs, ptr->layout.layouts[i].position);
 				if (ptr->layout.layouts[i].position==126) {
@@ -12736,10 +12778,18 @@ GF_Err chnl_box_write(GF_Box *s, GF_BitStream *bs)
 				}
 			}
 		} else {
-			gf_bs_write_u64(bs, ptr->layout.omittedChannelsMap);
+			if (ptr->version==1) {
+				gf_bs_write_int(bs, 0, 4);
+				gf_bs_write_int(bs, ptr->layout.channel_order_definition, 3);
+				gf_bs_write_int(bs, ptr->layout.omitted_channels_present, 1);
+				if (ptr->layout.omitted_channels_present)
+					gf_bs_write_u64(bs, ptr->layout.omittedChannelsMap);
+			} else {
+				gf_bs_write_u64(bs, ptr->layout.omittedChannelsMap);
+			}
 		}
 	}
-	if (ptr->layout.stream_structure & 2) {
+	if ((ptr->version==0) && (ptr->layout.stream_structure & 2)) {
 		gf_bs_write_u8(bs, ptr->layout.object_count);
 	}
 	return GF_OK;
@@ -12749,20 +12799,28 @@ GF_Err chnl_box_size(GF_Box *s)
 {
 	GF_ChannelLayoutBox *ptr = (GF_ChannelLayoutBox *) s;
 	s->size += 1;
+	if (ptr->version==1) s->size++;
 	if (ptr->layout.stream_structure & 1) {
 		s->size += 1;
 		if (ptr->layout.definedLayout==0) {
 			u32 i;
+			if (ptr->version==1) s->size++;
 			for (i=0; i<ptr->layout.channels_count; i++) {
 				s->size+=1;
 				if (ptr->layout.layouts[i].position==126)
 					s->size+=3;
 			}
 		} else {
-			s->size += 8;
+			if (ptr->version==1) {
+				s->size += 1;
+				if (ptr->layout.omitted_channels_present)
+					s->size += 8;
+			} else {
+				s->size += 8;
+			}
 		}
 	}
-	if (ptr->layout.stream_structure & 2) {
+	if ((ptr->version==0) && (ptr->layout.stream_structure & 2)) {
 		s->size += 1;
 	}
 	return GF_OK;

programming_language: C
filename: isom_write.c
change_type: ModificationType.MODIFY
diff: @@ -2512,6 +2512,10 @@ GF_Err gf_isom_set_audio_layout(GF_ISOFile *movie, u32 trackNumber, u32 sampleDe
 	e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE);
 	if (e) return e;
 
+	if (!layout) return GF_BAD_PARAM;
+	if ((layout->stream_structure & 1) && (layout->definedLayout==0) && (layout->channels_count>=64))
+		return GF_BAD_PARAM;
+
 	trak = gf_isom_get_track_from_file(movie, trackNumber);
 	if (!trak) return GF_BAD_PARAM;
 

programming_language: C