Commit message: Fix a couple buffer overflows

https://hackerone.com/reports/502816
https://hackerone.com/reports/507858

https://github.com/videolan/vlc/blob/master/contrib/src/faad2/faad2-fix-overflows.patch
CVE: CVE-2019-15296
CWE: CWE-119
Vulnerability description: An issue was discovered in Freeware Advanced Audio Decoder 2 (FAAD2) 2.8.8. The faad_resetbits function in libfaad/bits.c is affected by a buffer overflow vulnerability. The number of bits to be read is determined by ld->buffer_size - words*4, cast to uint32. If ld->buffer_size - words*4 is negative, a buffer overflow is later performed via getdword_n(&ld->start[words], ld->bytes_left).

Project: faad2

void faad_endbits(bitfile *ld)
{
}

Project: faad2

void faad_flushbits_ex(bitfile *ld, uint32_t bits)
{
    uint32_t tmp;

    ld->bufa = ld->bufb;
    if (ld->bytes_left >= 4)
    {
        tmp = getdword(ld->tail);
        ld->bytes_left -= 4;
    } else {
        tmp = getdword_n(ld->tail, ld->bytes_left);
        ld->bytes_left = 0;
    }
    ld->bufb = tmp;
    ld->tail++;
    ld->bits_left += (32 - bits);
}

Project: faad2
File: bits.c

void faad_initbits_rev(bitfile *ld, void *buffer,
                       uint32_t bits_in_buffer)
{
    uint32_t tmp;
    int32_t index;

    ld->buffer_size = bit2byte(bits_in_buffer);

    index = (bits_in_buffer+31)/32 - 1;

    ld->start = (uint32_t*)buffer + index - 2;

    tmp = getdword((uint32_t*)buffer + index);
    ld->bufa = tmp;

    tmp = getdword((uint32_t*)buffer + index - 1);
    ld->bufb = tmp;

    ld->tail = (uint32_t*)buffer + index;

    ld->bits_left = bits_in_buffer % 32;
    if (ld->bits_left == 0)
        ld->bits_left = 32;

    ld->bytes_left = ld->buffer_size;
    ld->error = 0;
}

Project: faad2
File: bits.c

void *faad_origbitbuffer(bitfile *ld)
{
    return (void*)ld->start;
}

Project: faad2

int8_t GASpecificConfig(bitfile *ld, mp4AudioSpecificConfig *mp4ASC,
                        program_config *pce_out)
{
    program_config pce;

    /* 1024 or 960 */
    mp4ASC->frameLengthFlag = faad_get1bit(ld
        DEBUGVAR(1,138,"GASpecificConfig(): FrameLengthFlag"));
#ifndef ALLOW_SMALL_FRAMELENGTH
    if (mp4ASC->frameLengthFlag == 1)
        return -3;
#endif

    mp4ASC->dependsOnCoreCoder = faad_get1bit(ld
        DEBUGVAR(1,139,"GASpecificConfig(): DependsOnCoreCoder"));
    if (mp4ASC->dependsOnCoreCoder == 1)
    {
        mp4ASC->coreCoderDelay = (uint16_t)faad_getbits(ld, 14
            DEBUGVAR(1,140,"GASpecificConfig(): CoreCoderDelay"));
    }

    mp4ASC->extensionFlag = faad_get1bit(ld DEBUGVAR(1,141,"GASpecificConfig(): ExtensionFlag"));
    if (mp4ASC->channelsConfiguration == 0)
    {
        if (program_config_element(&pce, ld))
            return -3;

        if (pce_out != NULL)
            memcpy(pce_out, &pce, sizeof(program_config));

        /*
        if (pce.num_valid_cc_elements)
            return -3;
        */
    }

#ifdef ERROR_RESILIENCE
    if (mp4ASC->extensionFlag == 1)
    {
        /* Error resilience not supported yet */
        if (mp4ASC->objectTypeIndex >= ER_OBJECT_START)
        {
            mp4ASC->aacSectionDataResilienceFlag = faad_get1bit(ld
                DEBUGVAR(1,144,"GASpecificConfig(): aacSectionDataResilienceFlag"));
            mp4ASC->aacScalefactorDataResilienceFlag = faad_get1bit(ld
                DEBUGVAR(1,145,"GASpecificConfig(): aacScalefactorDataResilienceFlag"));
            mp4ASC->aacSpectralDataResilienceFlag = faad_get1bit(ld
                DEBUGVAR(1,146,"GASpecificConfig(): aacSpectralDataResilienceFlag"));
        }
        /* 1 bit: extensionFlag3 */
        faad_getbits(ld, 1);
	}
#endif

    return 0;
}

Project: faad2
File: syntax.c

static uint8_t dynamic_range_info(bitfile *ld, drc_info *drc)
{
    uint8_t i, n = 1;
    uint8_t band_incr;

    drc->num_bands = 1;

    if (faad_get1bit(ld
        DEBUGVAR(1,90,"dynamic_range_info(): has instance_tag")) & 1)
    {
        drc->pce_instance_tag = (uint8_t)faad_getbits(ld, 4
            DEBUGVAR(1,91,"dynamic_range_info(): pce_instance_tag"));
        /* drc->drc_tag_reserved_bits = */ faad_getbits(ld, 4
            DEBUGVAR(1,92,"dynamic_range_info(): drc_tag_reserved_bits"));
        n++;
    }

    drc->excluded_chns_present = faad_get1bit(ld
        DEBUGVAR(1,93,"dynamic_range_info(): excluded_chns_present"));
    if (drc->excluded_chns_present == 1)
    {
        n += excluded_channels(ld, drc);
    }

    if (faad_get1bit(ld
        DEBUGVAR(1,94,"dynamic_range_info(): has bands data")) & 1)
    {
        band_incr = (uint8_t)faad_getbits(ld, 4
            DEBUGVAR(1,95,"dynamic_range_info(): band_incr"));
        /* drc->drc_bands_reserved_bits = */ faad_getbits(ld, 4
            DEBUGVAR(1,96,"dynamic_range_info(): drc_bands_reserved_bits"));
        n++;
        drc->num_bands += band_incr;

        for (i = 0; i < drc->num_bands; i++)
        {
            drc->band_top[i] = (uint8_t)faad_getbits(ld, 8
                DEBUGVAR(1,97,"dynamic_range_info(): band_top"));
            n++;
        }
    }

    if (faad_get1bit(ld
        DEBUGVAR(1,98,"dynamic_range_info(): has prog_ref_level")) & 1)
    {
        drc->prog_ref_level = (uint8_t)faad_getbits(ld, 7
            DEBUGVAR(1,99,"dynamic_range_info(): prog_ref_level"));
        /* drc->prog_ref_level_reserved_bits = */ faad_get1bit(ld
            DEBUGVAR(1,100,"dynamic_range_info(): prog_ref_level_reserved_bits"));
        n++;
    }

    for (i = 0; i < drc->num_bands; i++)
    {
        drc->dyn_rng_sgn[i] = faad_get1bit(ld
            DEBUGVAR(1,101,"dynamic_range_info(): dyn_rng_sgn"));
        drc->dyn_rng_ctl[i] = (uint8_t)faad_getbits(ld, 7
            DEBUGVAR(1,102,"dynamic_range_info(): dyn_rng_ctl"));
        n++;
    }

    return n;
}

Project: faad2

uint32_t faad_latm_frame(latm_header *latm, bitfile *ld)
{
    uint16_t len;
    uint32_t initpos, endpos, firstpos, ret;

    firstpos = faad_get_processed_bits(ld);
    while (ld->bytes_left)
    {
        faad_byte_align(ld);
        if(faad_showbits(ld, 11) != 0x2B7)
        {
            faad_getbits(ld, 8);
            continue;
        }
        faad_getbits(ld, 11);
        len = faad_getbits(ld, 13);
        if(!len)
            continue;
        initpos = faad_get_processed_bits(ld);
        ret = latmAudioMuxElement(latm, ld);
        endpos = faad_get_processed_bits(ld);
        if(ret>0)
            return (len*8)-(endpos-initpos);
    }
    return -1U;
}