CVE-2021-32439 (C, published 2021-08-11T20:15Z)
Description: value: Buffer overflow in the stbl_AppendSize function in MP4Box in GPAC 1.0.1 allows attackers to cause a denial of service or execute arbitrary code via a crafted file.
Severity: MEDIUM (CVSS v3 base score: 7.8)
Weakness: CWE-120 \u2014 Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')
The product copies an input buffer to an output buffer without verifying that the size of the input buffer is less than the size of the output buffer, leading to a buffer overflow.
Repository: https://github.com/gpac/gpac
Files changed:
src/isomedia/stbl_write.c
Commit message: fixed #1774 (fuzz)


Vulnerable code:
GF_Err stbl_AddDTS(GF_SampleTableBox *stbl, u64 DTS, u32 *sampleNumber, u32 LastAUDefDuration, u32 nb_packed_samples)
	if (!nb_packed_samples)
		nb_packed_samples=1;
		stts->entries[0].sampleCount = nb_packed_samples;
		stts->entries[0].sampleDelta = (nb_packed_samples>1) ? 0 : LastAUDefDuration;
		stts->w_currentSampleNum = nb_packed_samples;
			|| ((nb_packed_samples>1) && ((DTS == stts->w_LastDTS) || (DTS == stts->w_LastDTS + 2*ent->sampleDelta) ))
			ent->sampleCount += nb_packed_samples;
			stts->w_currentSampleNum += nb_packed_samples;
			stts->w_LastDTS = DTS + ent->sampleDelta * (nb_packed_samples-1);
		if (nb_packed_samples>1)
		if (nb_packed_samples==1) {
		ent->sampleCount = nb_packed_samples;
		stts->w_currentSampleNum += nb_packed_samples;
GF_Err stbl_AddSize(GF_SampleSizeBox *stsz, u32 sampleNumber, u32 size, u32 nb_pack_samples)
	if (!nb_pack_samples) nb_pack_samples = 1;
	else if (nb_pack_samples>1)
		size /= nb_pack_samples;
			stsz->sampleCount = nb_pack_samples;
			stsz->sampleCount += nb_pack_samples;
		if (nb_pack_samples>1) {
GF_Err stbl_AddChunkOffset(GF_MediaBox *mdia, u32 sampleNumber, u32 StreamDescIndex, u64 offset, u32 nb_pack_samples)
	if (!nb_pack_samples)
		nb_pack_samples = 1;
		stsc->w_lastSampleNumber = sampleNumber + nb_pack_samples-1;
	ent->samplesPerChunk = nb_pack_samples;
	if (sampleNumber + nb_pack_samples - 1 == stsc->w_lastSampleNumber) {
	if (!nb_pack) nb_pack = 1;
	if (!nb_pack) nb_pack = 1;
		if (stbl->SampleSize->sampleCount+nb_pack > stbl->SampleSize->alloc_size)

Fixed code:

#define CHECK_PACK(_e) \
	if (!nb_pack) nb_pack = 1; \
	else if ((s32) nb_pack < 0) { \
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Too many samples %u in packed sample\n", nb_pack)); \
		return _e; \
	}


GF_Err stbl_AddDTS(GF_SampleTableBox *stbl, u64 DTS, u32 *sampleNumber, u32 LastAUDefDuration, u32 nb_pack)

	CHECK_PACK(GF_BAD_PARAM)

		stts->entries[0].sampleCount = nb_pack;
		stts->entries[0].sampleDelta = (nb_pack>1) ? 0 : LastAUDefDuration;
		stts->w_currentSampleNum = nb_pack;
			|| ((nb_pack>1) && ((DTS == stts->w_LastDTS) || (DTS == stts->w_LastDTS + 2*ent->sampleDelta) ))
			ent->sampleCount += nb_pack;
			stts->w_currentSampleNum += nb_pack;
			stts->w_LastDTS = DTS + ent->sampleDelta * (nb_pack-1);
		if (nb_pack>1)
		if (nb_pack==1) {
		ent->sampleCount = nb_pack;
		stts->w_currentSampleNum += nb_pack;
GF_Err stbl_AddSize(GF_SampleSizeBox *stsz, u32 sampleNumber, u32 size, u32 nb_pack)
	CHECK_PACK(GF_BAD_PARAM)

	if (nb_pack>1)
		size /= nb_pack;

			stsz->sampleCount = nb_pack;
			stsz->sampleCount += nb_pack;
		if (nb_pack>1) {
GF_Err stbl_AddChunkOffset(GF_MediaBox *mdia, u32 sampleNumber, u32 StreamDescIndex, u64 offset, u32 nb_pack)
	CHECK_PACK(GF_BAD_PARAM)
		stsc->w_lastSampleNumber = sampleNumber + nb_pack-1;
	ent->samplesPerChunk = nb_pack;
	if (sampleNumber + nb_pack - 1 == stsc->w_lastSampleNumber) {
	CHECK_PACK(GF_ISOM_INVALID_FILE)

	CHECK_PACK(GF_ISOM_INVALID_FILE)

		if (stbl->SampleSize->sampleCount+nb_pack > stbl->SampleSize->alloc_size) {
		}