comparison h264.c @ 4362:0271b214458b libavcodec

harden h264 decoding to prevent some crashes when input data is corrupted. Patch by Frank %eucloid A gmail P com% date: Jan 18, 2007 6:48 PM subject: Re: [Ffmpeg-devel] h264, protection against corrupted data (second try patch) AND date: Jan 17, 2007 8:22 PM subject: [Ffmpeg-devel] h264, protection against corrupted data this also fixes a possible security issue (the sps and pps ids where not checked, then used as index into an array of sps/pps structs which was then filled with data from the bitstream)
author gpoirier
date Fri, 19 Jan 2007 09:37:04 +0000
parents d18568fb0187
children 9b7662fa4905
comparison
equal deleted inserted replaced
4361:f80a3b6c6f00 4362:0271b214458b
115 115
116 /** 116 /**
117 * Picture parameter set 117 * Picture parameter set
118 */ 118 */
119 typedef struct PPS{ 119 typedef struct PPS{
120 int sps_id; 120 unsigned int sps_id;
121 int cabac; ///< entropy_coding_mode_flag 121 int cabac; ///< entropy_coding_mode_flag
122 int pic_order_present; ///< pic_order_present_flag 122 int pic_order_present; ///< pic_order_present_flag
123 int slice_group_count; ///< num_slice_groups_minus1 + 1 123 int slice_group_count; ///< num_slice_groups_minus1 + 1
124 int mb_slice_group_map_type; 124 int mb_slice_group_map_type;
125 int ref_count[2]; ///< num_ref_idx_l0/1_active_minus1 + 1 125 int ref_count[2]; ///< num_ref_idx_l0/1_active_minus1 + 1
1778 } 1778 }
1779 1779
1780 h->rbsp_buffer= av_fast_realloc(h->rbsp_buffer, &h->rbsp_buffer_size, length); 1780 h->rbsp_buffer= av_fast_realloc(h->rbsp_buffer, &h->rbsp_buffer_size, length);
1781 dst= h->rbsp_buffer; 1781 dst= h->rbsp_buffer;
1782 1782
1783 if (dst == NULL){
1784 return NULL;
1785 }
1786
1783 //printf("decoding esc\n"); 1787 //printf("decoding esc\n");
1784 si=di=0; 1788 si=di=0;
1785 while(si<length){ 1789 while(si<length){
1786 //remove escapes (very rare 1:2^22) 1790 //remove escapes (very rare 1:2^22)
1787 if(si+2<length && src[si]==0 && src[si+1]==0 && src[si+2]<=3){ 1791 if(si+2<length && src[si]==0 && src[si+1]==0 && src[si+2]<=3){
3948 if(i>=0) 3952 if(i>=0)
3949 ref->pic_id= ref->frame_num; 3953 ref->pic_id= ref->frame_num;
3950 }else{ 3954 }else{
3951 pic_id= get_ue_golomb(&s->gb); //long_term_pic_idx 3955 pic_id= get_ue_golomb(&s->gb); //long_term_pic_idx
3952 ref = h->long_ref[pic_id]; 3956 ref = h->long_ref[pic_id];
3953 ref->pic_id= pic_id; 3957 if(ref){
3954 assert(ref->reference == 3); 3958 ref->pic_id= pic_id;
3955 assert(ref->long_ref); 3959 assert(ref->reference == 3);
3956 i=0; 3960 assert(ref->long_ref);
3961 i=0;
3962 }else{
3963 i=-1;
3964 }
3957 } 3965 }
3958 3966
3959 if (i < 0) { 3967 if (i < 0) {
3960 av_log(h->s.avctx, AV_LOG_ERROR, "reference picture missing during reorder\n"); 3968 av_log(h->s.avctx, AV_LOG_ERROR, "reference picture missing during reorder\n");
3961 memset(&h->ref_list[list][index], 0, sizeof(Picture)); //FIXME 3969 memset(&h->ref_list[list][index], 0, sizeof(Picture)); //FIXME
4257 case MMCO_SHORT2LONG: 4265 case MMCO_SHORT2LONG:
4258 pic= remove_long(h, mmco[i].long_index); 4266 pic= remove_long(h, mmco[i].long_index);
4259 if(pic) unreference_pic(h, pic); 4267 if(pic) unreference_pic(h, pic);
4260 4268
4261 h->long_ref[ mmco[i].long_index ]= remove_short(h, mmco[i].short_frame_num); 4269 h->long_ref[ mmco[i].long_index ]= remove_short(h, mmco[i].short_frame_num);
4262 h->long_ref[ mmco[i].long_index ]->long_ref=1; 4270 if (h->long_ref[ mmco[i].long_index ]){
4263 h->long_ref_count++; 4271 h->long_ref[ mmco[i].long_index ]->long_ref=1;
4272 h->long_ref_count++;
4273 }
4264 break; 4274 break;
4265 case MMCO_LONG2UNUSED: 4275 case MMCO_LONG2UNUSED:
4266 pic= remove_long(h, mmco[i].long_index); 4276 pic= remove_long(h, mmco[i].long_index);
4267 if(pic) 4277 if(pic)
4268 unreference_pic(h, pic); 4278 unreference_pic(h, pic);
4288 } 4298 }
4289 break; 4299 break;
4290 case MMCO_RESET: 4300 case MMCO_RESET:
4291 while(h->short_ref_count){ 4301 while(h->short_ref_count){
4292 pic= remove_short(h, h->short_ref[0]->frame_num); 4302 pic= remove_short(h, h->short_ref[0]->frame_num);
4293 unreference_pic(h, pic); 4303 if(pic) unreference_pic(h, pic);
4294 } 4304 }
4295 for(j = 0; j < 16; j++) { 4305 for(j = 0; j < 16; j++) {
4296 pic= remove_long(h, j); 4306 pic= remove_long(h, j);
4297 if(pic) unreference_pic(h, pic); 4307 if(pic) unreference_pic(h, pic);
4298 } 4308 }
4471 * decodes a slice header. 4481 * decodes a slice header.
4472 * this will allso call MPV_common_init() and frame_start() as needed 4482 * this will allso call MPV_common_init() and frame_start() as needed
4473 */ 4483 */
4474 static int decode_slice_header(H264Context *h){ 4484 static int decode_slice_header(H264Context *h){
4475 MpegEncContext * const s = &h->s; 4485 MpegEncContext * const s = &h->s;
4476 int first_mb_in_slice, pps_id; 4486 int first_mb_in_slice;
4487 unsigned int pps_id;
4477 int num_ref_idx_active_override_flag; 4488 int num_ref_idx_active_override_flag;
4478 static const uint8_t slice_type_map[5]= {P_TYPE, B_TYPE, I_TYPE, SP_TYPE, SI_TYPE}; 4489 static const uint8_t slice_type_map[5]= {P_TYPE, B_TYPE, I_TYPE, SP_TYPE, SI_TYPE};
4479 int slice_type; 4490 int slice_type;
4480 int default_ref_list_done = 0; 4491 int default_ref_list_done = 0;
4481 4492
4503 h->slice_type= slice_type; 4514 h->slice_type= slice_type;
4504 4515
4505 s->pict_type= h->slice_type; // to make a few old func happy, it's wrong though 4516 s->pict_type= h->slice_type; // to make a few old func happy, it's wrong though
4506 4517
4507 pps_id= get_ue_golomb(&s->gb); 4518 pps_id= get_ue_golomb(&s->gb);
4508 if(pps_id>255){ 4519 if(pps_id>=MAX_PPS_COUNT){
4509 av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n"); 4520 av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n");
4510 return -1; 4521 return -1;
4511 } 4522 }
4512 h->pps= h->pps_buffer[pps_id]; 4523 h->pps= h->pps_buffer[pps_id];
4513 if(h->pps.slice_group_count == 0){ 4524 if(h->pps.slice_group_count == 0){
4519 if(h->sps.log2_max_frame_num == 0){ 4530 if(h->sps.log2_max_frame_num == 0){
4520 av_log(h->s.avctx, AV_LOG_ERROR, "non existing SPS referenced\n"); 4531 av_log(h->s.avctx, AV_LOG_ERROR, "non existing SPS referenced\n");
4521 return -1; 4532 return -1;
4522 } 4533 }
4523 4534
4524 if(h->dequant_coeff_pps != pps_id){ 4535 if(h->dequant_coeff_pps != (int)pps_id){
4525 h->dequant_coeff_pps = pps_id; 4536 h->dequant_coeff_pps = (int)pps_id;
4526 init_dequant_tables(h); 4537 init_dequant_tables(h);
4527 } 4538 }
4528 4539
4529 s->mb_width= h->sps.mb_width; 4540 s->mb_width= h->sps.mb_width;
4530 s->mb_height= h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag); 4541 s->mb_height= h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);
4760 4771
4761 h->emu_edge_width= (s->flags&CODEC_FLAG_EMU_EDGE) ? 0 : 16; 4772 h->emu_edge_width= (s->flags&CODEC_FLAG_EMU_EDGE) ? 0 : 16;
4762 h->emu_edge_height= FRAME_MBAFF ? 0 : h->emu_edge_width; 4773 h->emu_edge_height= FRAME_MBAFF ? 0 : h->emu_edge_width;
4763 4774
4764 if(s->avctx->debug&FF_DEBUG_PICT_INFO){ 4775 if(s->avctx->debug&FF_DEBUG_PICT_INFO){
4765 av_log(h->s.avctx, AV_LOG_DEBUG, "slice:%d %s mb:%d %c pps:%d frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s\n", 4776 av_log(h->s.avctx, AV_LOG_DEBUG, "slice:%d %s mb:%d %c pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s\n",
4766 h->slice_num, 4777 h->slice_num,
4767 (s->picture_structure==PICT_FRAME ? "F" : s->picture_structure==PICT_TOP_FIELD ? "T" : "B"), 4778 (s->picture_structure==PICT_FRAME ? "F" : s->picture_structure==PICT_TOP_FIELD ? "T" : "B"),
4768 first_mb_in_slice, 4779 first_mb_in_slice,
4769 av_get_pict_type_char(h->slice_type), 4780 av_get_pict_type_char(h->slice_type),
4770 pps_id, h->frame_num, 4781 pps_id, h->frame_num,
7670 } 7681 }
7671 7682
7672 static inline int decode_seq_parameter_set(H264Context *h){ 7683 static inline int decode_seq_parameter_set(H264Context *h){
7673 MpegEncContext * const s = &h->s; 7684 MpegEncContext * const s = &h->s;
7674 int profile_idc, level_idc; 7685 int profile_idc, level_idc;
7675 int sps_id, i; 7686 unsigned int sps_id;
7687 int i;
7676 SPS *sps; 7688 SPS *sps;
7677 7689
7678 profile_idc= get_bits(&s->gb, 8); 7690 profile_idc= get_bits(&s->gb, 8);
7679 get_bits1(&s->gb); //constraint_set0_flag 7691 get_bits1(&s->gb); //constraint_set0_flag
7680 get_bits1(&s->gb); //constraint_set1_flag 7692 get_bits1(&s->gb); //constraint_set1_flag
7681 get_bits1(&s->gb); //constraint_set2_flag 7693 get_bits1(&s->gb); //constraint_set2_flag
7682 get_bits1(&s->gb); //constraint_set3_flag 7694 get_bits1(&s->gb); //constraint_set3_flag
7683 get_bits(&s->gb, 4); // reserved 7695 get_bits(&s->gb, 4); // reserved
7684 level_idc= get_bits(&s->gb, 8); 7696 level_idc= get_bits(&s->gb, 8);
7685 sps_id= get_ue_golomb(&s->gb); 7697 sps_id= get_ue_golomb(&s->gb);
7698
7699 if (sps_id >= MAX_SPS_COUNT){
7700 // ok it has gone out of hand, someone is sending us bad stuff.
7701 av_log(h->s.avctx, AV_LOG_ERROR, "illegal sps_id (%d)\n", sps_id);
7702 return -1;
7703 }
7686 7704
7687 sps= &h->sps_buffer[ sps_id ]; 7705 sps= &h->sps_buffer[ sps_id ];
7688 sps->profile_idc= profile_idc; 7706 sps->profile_idc= profile_idc;
7689 sps->level_idc= level_idc; 7707 sps->level_idc= level_idc;
7690 7708
7762 sps->vui_parameters_present_flag= get_bits1(&s->gb); 7780 sps->vui_parameters_present_flag= get_bits1(&s->gb);
7763 if( sps->vui_parameters_present_flag ) 7781 if( sps->vui_parameters_present_flag )
7764 decode_vui_parameters(h, sps); 7782 decode_vui_parameters(h, sps);
7765 7783
7766 if(s->avctx->debug&FF_DEBUG_PICT_INFO){ 7784 if(s->avctx->debug&FF_DEBUG_PICT_INFO){
7767 av_log(h->s.avctx, AV_LOG_DEBUG, "sps:%d profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s\n", 7785 av_log(h->s.avctx, AV_LOG_DEBUG, "sps:%u profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s\n",
7768 sps_id, sps->profile_idc, sps->level_idc, 7786 sps_id, sps->profile_idc, sps->level_idc,
7769 sps->poc_type, 7787 sps->poc_type,
7770 sps->ref_frame_count, 7788 sps->ref_frame_count,
7771 sps->mb_width, sps->mb_height, 7789 sps->mb_width, sps->mb_height,
7772 sps->frame_mbs_only_flag ? "FRM" : (sps->mb_aff ? "MB-AFF" : "PIC-AFF"), 7790 sps->frame_mbs_only_flag ? "FRM" : (sps->mb_aff ? "MB-AFF" : "PIC-AFF"),
7779 return 0; 7797 return 0;
7780 } 7798 }
7781 7799
7782 static inline int decode_picture_parameter_set(H264Context *h, int bit_length){ 7800 static inline int decode_picture_parameter_set(H264Context *h, int bit_length){
7783 MpegEncContext * const s = &h->s; 7801 MpegEncContext * const s = &h->s;
7784 int pps_id= get_ue_golomb(&s->gb); 7802 unsigned int pps_id= get_ue_golomb(&s->gb);
7785 PPS *pps= &h->pps_buffer[pps_id]; 7803 PPS *pps;
7804
7805 if(pps_id>=MAX_PPS_COUNT){
7806 av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n");
7807 return -1;
7808 }
7809 pps = &h->pps_buffer[pps_id];
7786 7810
7787 pps->sps_id= get_ue_golomb(&s->gb); 7811 pps->sps_id= get_ue_golomb(&s->gb);
7788 pps->cabac= get_bits1(&s->gb); 7812 pps->cabac= get_bits1(&s->gb);
7789 pps->pic_order_present= get_bits1(&s->gb); 7813 pps->pic_order_present= get_bits1(&s->gb);
7790 pps->slice_group_count= get_ue_golomb(&s->gb) + 1; 7814 pps->slice_group_count= get_ue_golomb(&s->gb) + 1;
7851 decode_scaling_matrices(h, &h->sps_buffer[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8); 7875 decode_scaling_matrices(h, &h->sps_buffer[pps->sps_id], pps, 0, pps->scaling_matrix4, pps->scaling_matrix8);
7852 get_se_golomb(&s->gb); //second_chroma_qp_index_offset 7876 get_se_golomb(&s->gb); //second_chroma_qp_index_offset
7853 } 7877 }
7854 7878
7855 if(s->avctx->debug&FF_DEBUG_PICT_INFO){ 7879 if(s->avctx->debug&FF_DEBUG_PICT_INFO){
7856 av_log(h->s.avctx, AV_LOG_DEBUG, "pps:%d sps:%d %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d %s %s %s %s\n", 7880 av_log(h->s.avctx, AV_LOG_DEBUG, "pps:%u sps:%u %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d %s %s %s %s\n",
7857 pps_id, pps->sps_id, 7881 pps_id, pps->sps_id,
7858 pps->cabac ? "CABAC" : "CAVLC", 7882 pps->cabac ? "CABAC" : "CAVLC",
7859 pps->slice_group_count, 7883 pps->slice_group_count,
7860 pps->ref_count[0], pps->ref_count[1], 7884 pps->ref_count[0], pps->ref_count[1],
7861 pps->weighted_pred ? "weighted" : "", 7885 pps->weighted_pred ? "weighted" : "",
7985 if(h->is_avc) { 8009 if(h->is_avc) {
7986 if(buf_index >= buf_size) break; 8010 if(buf_index >= buf_size) break;
7987 nalsize = 0; 8011 nalsize = 0;
7988 for(i = 0; i < h->nal_length_size; i++) 8012 for(i = 0; i < h->nal_length_size; i++)
7989 nalsize = (nalsize << 8) | buf[buf_index++]; 8013 nalsize = (nalsize << 8) | buf[buf_index++];
7990 if(nalsize <= 1){ 8014 if(nalsize <= 1 || nalsize > buf_size){
7991 if(nalsize == 1){ 8015 if(nalsize == 1){
7992 buf_index++; 8016 buf_index++;
7993 continue; 8017 continue;
7994 }else{ 8018 }else{
7995 av_log(h->s.avctx, AV_LOG_ERROR, "AVC: nal size %d\n", nalsize); 8019 av_log(h->s.avctx, AV_LOG_ERROR, "AVC: nal size %d\n", nalsize);
8008 8032
8009 buf_index+=3; 8033 buf_index+=3;
8010 } 8034 }
8011 8035
8012 ptr= decode_nal(h, buf + buf_index, &dst_length, &consumed, h->is_avc ? nalsize : buf_size - buf_index); 8036 ptr= decode_nal(h, buf + buf_index, &dst_length, &consumed, h->is_avc ? nalsize : buf_size - buf_index);
8037 if (ptr==NULL || dst_length <= 0){
8038 return -1;
8039 }
8013 while(ptr[dst_length - 1] == 0 && dst_length > 1) 8040 while(ptr[dst_length - 1] == 0 && dst_length > 1)
8014 dst_length--; 8041 dst_length--;
8015 bit_length= 8*dst_length - decode_rbsp_trailing(ptr + dst_length - 1); 8042 bit_length= 8*dst_length - decode_rbsp_trailing(ptr + dst_length - 1);
8016 8043
8017 if(s->avctx->debug&FF_DEBUG_STARTCODE){ 8044 if(s->avctx->debug&FF_DEBUG_STARTCODE){