Commit message: avcodec/h264: Clear delayed_pic on deallocation

Fixes use of freed memory

Fixes: case5_av_frame_copy_props.mp4
Found-by: Michal Zalewski <lcamtuf@coredump.cx>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
CVE: CVE-2015-3417
CWE: CWE-703
Vulnerability description: Use-after-free vulnerability in the ff_h264_free_tables function in libavcodec/h264.c in FFmpeg before 2.3.6 allows remote attackers to cause a denial of service or possibly have unspecified other impact via crafted H.264 data in an MP4 file, as demonstrated by an HTML VIDEO element that references H.264 data.

Project: FFmpeg

av_cold int ff_h264_decode_init(AVCodecContext *avctx)
{
    H264Context *h = avctx->priv_data;
    int i;
    int ret;

    h->avctx = avctx;

    h->bit_depth_luma    = 8;
    h->chroma_format_idc = 1;

    h->avctx->bits_per_raw_sample = 8;
    h->cur_chroma_format_idc = 1;

    ff_h264dsp_init(&h->h264dsp, 8, 1);
    av_assert0(h->sps.bit_depth_chroma == 0);
    ff_h264chroma_init(&h->h264chroma, h->sps.bit_depth_chroma);
    ff_h264qpel_init(&h->h264qpel, 8);
    ff_h264_pred_init(&h->hpc, h->avctx->codec_id, 8, 1);

    h->dequant_coeff_pps = -1;
    h->current_sps_id = -1;

    /* needed so that IDCT permutation is known early */
    if (CONFIG_ERROR_RESILIENCE)
        ff_me_cmp_init(&h->mecc, h->avctx);
    ff_videodsp_init(&h->vdsp, 8);

    memset(h->pps.scaling_matrix4, 16, 6 * 16 * sizeof(uint8_t));
    memset(h->pps.scaling_matrix8, 16, 2 * 64 * sizeof(uint8_t));

    h->picture_structure   = PICT_FRAME;
    h->slice_context_count = 1;
    h->workaround_bugs     = avctx->workaround_bugs;
    h->flags               = avctx->flags;

    /* set defaults */
    if (!avctx->has_b_frames)
        h->low_delay = 1;

    avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;

    ff_h264_decode_init_vlc();

    ff_init_cabac_states();

    h->pixel_shift        = 0;
    h->sps.bit_depth_luma = avctx->bits_per_raw_sample = 8;

    h->thread_context[0] = h;
    h->outputed_poc      = h->next_outputed_poc = INT_MIN;
    for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
        h->last_pocs[i] = INT_MIN;
    h->prev_poc_msb = 1 << 16;
    h->prev_frame_num = -1;
    h->x264_build   = -1;
    h->sei_fpa.frame_packing_arrangement_cancel_flag = -1;
    ff_h264_reset_sei(h);
    if (avctx->codec_id == AV_CODEC_ID_H264) {
        if (avctx->ticks_per_frame == 1) {
            if(h->avctx->time_base.den < INT_MAX/2) {
                h->avctx->time_base.den *= 2;
            } else
                h->avctx->time_base.num /= 2;
        }
        avctx->ticks_per_frame = 2;
    }

    if (avctx->extradata_size > 0 && avctx->extradata) {
        ret = ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size);
        if (ret < 0) {
            ff_h264_free_context(h);
            return ret;
        }
    }

    if (h->sps.bitstream_restriction_flag &&
        h->avctx->has_b_frames < h->sps.num_reorder_frames) {
        h->avctx->has_b_frames = h->sps.num_reorder_frames;
        h->low_delay           = 0;
    }

    avctx->internal->allocate_progress = 1;

    ff_h264_flush_change(h);

    return 0;
}

Project: FFmpeg

int ff_set_ref_count(H264Context *h)
{
    int ref_count[2], list_count;
    int num_ref_idx_active_override_flag;

    ref_count[0] = h->pps.ref_count[0];
    ref_count[1] = h->pps.ref_count[1];

    if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
        unsigned max[2];
        max[0] = max[1] = h->picture_structure == PICT_FRAME ? 15 : 31;

        if (h->slice_type_nos == AV_PICTURE_TYPE_B)
            h->direct_spatial_mv_pred = get_bits1(&h->gb);
        num_ref_idx_active_override_flag = get_bits1(&h->gb);

        if (num_ref_idx_active_override_flag) {
            ref_count[0] = get_ue_golomb(&h->gb) + 1;
            if (h->slice_type_nos == AV_PICTURE_TYPE_B) {
                ref_count[1] = get_ue_golomb(&h->gb) + 1;
            } else
                ref_count[1] = 1;
        }

        if (ref_count[0]-1 > max[0] || ref_count[1]-1 > max[1]){
            av_log(h->avctx, AV_LOG_ERROR, "reference overflow %u > %u or %u > %u\n", ref_count[0]-1, max[0], ref_count[1]-1, max[1]);
            h->ref_count[0] = h->ref_count[1] = 0;
            h->list_count   = 0;
            return AVERROR_INVALIDDATA;
        }

        if (h->slice_type_nos == AV_PICTURE_TYPE_B)
            list_count = 2;
        else
            list_count = 1;
    } else {
        list_count   = 0;
        ref_count[0] = ref_count[1] = 0;
    }

    if (list_count != h->list_count ||
        ref_count[0] != h->ref_count[0] ||
        ref_count[1] != h->ref_count[1]) {
        h->ref_count[0] = ref_count[0];
        h->ref_count[1] = ref_count[1];
        h->list_count   = list_count;
        return 1;
    }

    return 0;
}

Project: FFmpeg
File: h264.c

static int get_last_needed_nal(H264Context *h, const uint8_t *buf, int buf_size)
{
    int next_avc    = h->is_avc ? 0 : buf_size;
    int nal_index   = 0;
    int buf_index   = 0;
    int nals_needed = 0;
    int first_slice = 0;

    while(1) {
        int nalsize = 0;
        int dst_length, bit_length, consumed;
        const uint8_t *ptr;

        if (buf_index >= next_avc) {
            nalsize = get_avc_nalsize(h, buf, buf_size, &buf_index);
            if (nalsize < 0)
                break;
            next_avc = buf_index + nalsize;
        } else {
            buf_index = find_start_code(buf, buf_size, buf_index, next_avc);
            if (buf_index >= buf_size)
                break;
            if (buf_index >= next_avc)
                continue;
        }

        ptr = ff_h264_decode_nal(h, buf + buf_index, &dst_length, &consumed,
                                 next_avc - buf_index);

        if (!ptr || dst_length < 0)
            return AVERROR_INVALIDDATA;

        buf_index += consumed;

        bit_length = get_bit_length(h, buf, ptr, dst_length,
                                    buf_index, next_avc);
        nal_index++;

        /* packets can sometimes contain multiple PPS/SPS,
         * e.g. two PAFF field pictures in one packet, or a demuxer
         * which splits NALs strangely if so, when frame threading we
         * can't start the next thread until we've read all of them */
        switch (h->nal_unit_type) {
        case NAL_SPS:
        case NAL_PPS:
            nals_needed = nal_index;
            break;
        case NAL_DPA:
        case NAL_IDR_SLICE:
        case NAL_SLICE:
            init_get_bits(&h->gb, ptr, bit_length);
            if (!get_ue_golomb(&h->gb) ||
                !first_slice ||
                first_slice != h->nal_unit_type)
                nals_needed = nal_index;
            if (!first_slice)
                first_slice = h->nal_unit_type;
        }
    }

    return nals_needed;
}