CVE-2023-4758: Out-of-bounds Read (CWE-125)
value: Buffer Over-read in GitHub repository gpac/gpac prior to 2.3-DEV.
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 5.5
Published: 2023-09-04T16:15Z
Repository: https://github.com/gpac/gpac
Language: C
Files changed: src/media_tools/avilib.c
Commit date: 2023-08-31 11:37:34 +0200
Commit message: fixed #2573

Diff: diff --git a/src/media_tools/avilib.c b/src/media_tools/avilib.c
index 7cdca7d87d4..459ff804389 100644
--- a/src/media_tools/avilib.c
+++ b/src/media_tools/avilib.c
@@ -2075,15 +2075,17 @@ int avi_parse_input_file(avi_t *AVI, int getIndex)
 					if(lasttag == 1)
 					{
 						alBITMAPINFOHEADER bih;
 
 						memcpy(&bih, hdrl_data + i, sizeof(alBITMAPINFOHEADER));
-						AVI->bitmap_info_header = (alBITMAPINFOHEADER *)
-						                          gf_malloc(str2ulong((unsigned char *)&bih.bi_size));
+						bih.bi_size = str2ulong((unsigned char *)&bih.bi_size);
+
+						if (i + bih.bi_size > hdrl_len) ERR_EXIT(AVI_ERR_READ)
+
+						AVI->bitmap_info_header = (alBITMAPINFOHEADER *) gf_malloc(bih.bi_size);
 						if (AVI->bitmap_info_header != NULL)
-							memcpy(AVI->bitmap_info_header, hdrl_data + i,
-							       str2ulong((unsigned char *)&bih.bi_size));
+							memcpy(AVI->bitmap_info_header, hdrl_data + i, bih.bi_size);
 
 						AVI->width  = str2ulong(hdrl_data+i+4);
 						AVI->height = str2ulong(hdrl_data+i+8);
 						vids_strf_seen = 1;
 						//ThOe
@@ -2152,10 +2154,12 @@ int avi_parse_input_file(avi_t *AVI, int getIndex)
 
 					if(lasttag == 1) // V I D E O
 					{
 
 						a = (char*)hdrl_data+i;
+						int avail = hdrl_len-i;
+						if (avail<32) ERR_EXIT(AVI_ERR_READ)
 
 						AVI->video_superindex = (avisuperindex_chunk *) gf_malloc (sizeof (avisuperindex_chunk));
 						memset(AVI->video_superindex, 0, sizeof (avisuperindex_chunk));
 						memcpy (AVI->video_superindex->fcc, a, 4);
 						a += 4;
@@ -2178,10 +2182,12 @@ int avi_parse_input_file(avi_t *AVI, int getIndex)
 						a += 4;
 
 						if (AVI->video_superindex->bIndexSubType != 0) {
 							GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] Invalid Header, bIndexSubType != 0\n"));
 						}
+						avail -= 32;
+						if (avail < AVI->video_superindex->nEntriesInUse*16) ERR_EXIT(AVI_ERR_READ)
 
 						AVI->video_superindex->aIndex = (avisuperindex_entry*)
 						                                gf_malloc (AVI->video_superindex->wLongsPerEntry * AVI->video_superindex->nEntriesInUse * sizeof (u32));
 
 						// position of ix## chunks
@@ -2219,10 +2225,12 @@ int avi_parse_input_file(avi_t *AVI, int getIndex)
 					}
 					else if(lasttag == 2) // A U D I O
 					{
 
 						a = (char*) hdrl_data+i;
+						int avail = hdrl_len-i;
+						if (avail<32) ERR_EXIT(AVI_ERR_READ)
 
 						AVI->track[AVI->aptr].audio_superindex = (avisuperindex_chunk *) gf_malloc (sizeof (avisuperindex_chunk));
 						memcpy (AVI->track[AVI->aptr].audio_superindex->fcc, a, 4);
 						a += 4;
 						AVI->track[AVI->aptr].audio_superindex->dwSize = str2ulong((unsigned char*)a);
@@ -2245,10 +2253,13 @@ int avi_parse_input_file(avi_t *AVI, int getIndex)
 
 						if (AVI->track[AVI->aptr].audio_superindex->bIndexSubType != 0) {
 							GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] Invalid Header, bIndexSubType != 0\n"));
 						}
 
+						avail -= 32;
+						if (avail < AVI->track[AVI->aptr].audio_superindex->nEntriesInUse*16) ERR_EXIT(AVI_ERR_READ)
+
 						AVI->track[AVI->aptr].audio_superindex->aIndex = (avisuperindex_entry*)
 						        gf_malloc (AVI->track[AVI->aptr].audio_superindex->wLongsPerEntry *
 						                   AVI->track[AVI->aptr].audio_superindex->nEntriesInUse * sizeof (u32));
 
 						// position of ix## chunks

Vulnerable code: 						AVI->bitmap_info_header = (alBITMAPINFOHEADER *)
						                          gf_malloc(str2ulong((unsigned char *)&bih.bi_size));
							memcpy(AVI->bitmap_info_header, hdrl_data + i,
							       str2ulong((unsigned char *)&bih.bi_size));
Fixed code: 						bih.bi_size = str2ulong((unsigned char *)&bih.bi_size);

						if (i + bih.bi_size > hdrl_len) ERR_EXIT(AVI_ERR_READ)

						AVI->bitmap_info_header = (alBITMAPINFOHEADER *) gf_malloc(bih.bi_size);
							memcpy(AVI->bitmap_info_header, hdrl_data + i, bih.bi_size);
						int avail = hdrl_len-i;
						if (avail<32) ERR_EXIT(AVI_ERR_READ)
						avail -= 32;
						if (avail < AVI->video_superindex->nEntriesInUse*16) ERR_EXIT(AVI_ERR_READ)
						int avail = hdrl_len-i;
						if (avail<32) ERR_EXIT(AVI_ERR_READ)
						avail -= 32;
						if (avail < AVI->track[AVI->aptr].audio_superindex->nEntriesInUse*16) ERR_EXIT(AVI_ERR_READ)