Mercurial > libavformat.hg
comparison mov.c @ 639:0b52743104ac libavformat
integer overflows, heap corruption
possible arbitrary code execution cannot be ruled out in some cases
precautionary checks
author | michael |
---|---|
date | Sat, 08 Jan 2005 14:21:33 +0000 |
parents | adc5295cd0a2 |
children | 6f3a6774df82 |
comparison
equal
deleted
inserted
replaced
638:5188094c6ec4 | 639:0b52743104ac |
---|---|
365 for (i = 0; c->parse_table[i].type != 0L | 365 for (i = 0; c->parse_table[i].type != 0L |
366 && c->parse_table[i].type != a.type; i++) | 366 && c->parse_table[i].type != a.type; i++) |
367 /* empty */; | 367 /* empty */; |
368 | 368 |
369 a.size -= 8; | 369 a.size -= 8; |
370 | |
371 if(a.size < 0) | |
372 break; | |
373 | |
370 // av_log(NULL, AV_LOG_DEBUG, " i=%ld\n", i); | 374 // av_log(NULL, AV_LOG_DEBUG, " i=%ld\n", i); |
371 if (c->parse_table[i].type == 0) { /* skip leaf atoms data */ | 375 if (c->parse_table[i].type == 0) { /* skip leaf atoms data */ |
372 // url_seek(pb, atom.offset+atom.size, SEEK_SET); | 376 // url_seek(pb, atom.offset+atom.size, SEEK_SET); |
373 #ifdef DEBUG | 377 #ifdef DEBUG |
374 print_atom("unknown", a); | 378 print_atom("unknown", a); |
399 | 403 |
400 static int mov_read_ctab(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) | 404 static int mov_read_ctab(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) |
401 { | 405 { |
402 unsigned int len; | 406 unsigned int len; |
403 MOV_ctab_t *t; | 407 MOV_ctab_t *t; |
404 //url_fskip(pb, atom.size); // for now | 408 #if 1 |
409 url_fskip(pb, atom.size); // for now | |
410 #else | |
411 VERY VERY BROKEN, NEVER execute this, needs rewrite | |
405 c->ctab = av_realloc(c->ctab, ++c->ctab_size); | 412 c->ctab = av_realloc(c->ctab, ++c->ctab_size); |
406 t = c->ctab[c->ctab_size]; | 413 t = c->ctab[c->ctab_size]; |
407 t->seed = get_be32(pb); | 414 t->seed = get_be32(pb); |
408 t->flags = get_be16(pb); | 415 t->flags = get_be16(pb); |
409 t->size = get_be16(pb) + 1; | 416 t->size = get_be16(pb) + 1; |
411 if (len > 0) { | 418 if (len > 0) { |
412 t->clrs = av_malloc(len); // 16bit A R G B | 419 t->clrs = av_malloc(len); // 16bit A R G B |
413 if (t->clrs) | 420 if (t->clrs) |
414 get_buffer(pb, t->clrs, len); | 421 get_buffer(pb, t->clrs, len); |
415 } | 422 } |
423 #endif | |
416 | 424 |
417 return 0; | 425 return 0; |
418 } | 426 } |
419 | 427 |
420 static int mov_read_hdlr(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) | 428 static int mov_read_hdlr(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) |
675 | 683 |
676 static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) | 684 static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) |
677 { | 685 { |
678 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; | 686 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; |
679 | 687 |
688 if((uint64_t)atom.size > (1<<30)) | |
689 return -1; | |
690 | |
680 // currently SVQ3 decoder expect full STSD header - so let's fake it | 691 // currently SVQ3 decoder expect full STSD header - so let's fake it |
681 // this should be fixed and just SMI header should be passed | 692 // this should be fixed and just SMI header should be passed |
682 av_free(st->codec.extradata); | 693 av_free(st->codec.extradata); |
683 st->codec.extradata_size = 0x5a + atom.size; | 694 st->codec.extradata_size = 0x5a + atom.size; |
684 st->codec.extradata = (uint8_t*) av_mallocz(st->codec.extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); | 695 st->codec.extradata = (uint8_t*) av_mallocz(st->codec.extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); |
695 | 706 |
696 static int mov_read_avcC(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) | 707 static int mov_read_avcC(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) |
697 { | 708 { |
698 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; | 709 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; |
699 | 710 |
711 if((uint64_t)atom.size > (1<<30)) | |
712 return -1; | |
713 | |
700 av_free(st->codec.extradata); | 714 av_free(st->codec.extradata); |
701 | 715 |
702 st->codec.extradata_size = atom.size; | 716 st->codec.extradata_size = atom.size; |
703 st->codec.extradata = (uint8_t*) av_mallocz(st->codec.extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); | 717 st->codec.extradata = (uint8_t*) av_mallocz(st->codec.extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); |
704 | 718 |
712 | 726 |
713 static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) | 727 static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) |
714 { | 728 { |
715 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; | 729 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; |
716 MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; | 730 MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; |
717 int entries, i; | 731 unsigned int i, entries; |
718 | 732 |
719 print_atom("stco", atom); | 733 print_atom("stco", atom); |
720 | 734 |
721 get_byte(pb); /* version */ | 735 get_byte(pb); /* version */ |
722 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ | 736 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ |
723 | 737 |
724 entries = get_be32(pb); | 738 entries = get_be32(pb); |
739 | |
740 if(entries >= UINT_MAX/sizeof(int64_t)) | |
741 return -1; | |
742 | |
725 sc->chunk_count = entries; | 743 sc->chunk_count = entries; |
726 sc->chunk_offsets = (int64_t*) av_malloc(entries * sizeof(int64_t)); | 744 sc->chunk_offsets = (int64_t*) av_malloc(entries * sizeof(int64_t)); |
727 if (!sc->chunk_offsets) | 745 if (!sc->chunk_offsets) |
728 return -1; | 746 return -1; |
729 if (atom.type == MKTAG('s', 't', 'c', 'o')) { | 747 if (atom.type == MKTAG('s', 't', 'c', 'o')) { |
1136 | 1154 |
1137 static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) | 1155 static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) |
1138 { | 1156 { |
1139 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; | 1157 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; |
1140 MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; | 1158 MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; |
1141 int entries, i; | 1159 unsigned int i, entries; |
1142 | 1160 |
1143 print_atom("stsc", atom); | 1161 print_atom("stsc", atom); |
1144 | 1162 |
1145 get_byte(pb); /* version */ | 1163 get_byte(pb); /* version */ |
1146 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ | 1164 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ |
1147 | 1165 |
1148 entries = get_be32(pb); | 1166 entries = get_be32(pb); |
1167 | |
1168 if(entries >= UINT_MAX / sizeof(MOV_sample_to_chunk_tbl)) | |
1169 return -1; | |
1170 | |
1149 #ifdef DEBUG | 1171 #ifdef DEBUG |
1150 av_log(NULL, AV_LOG_DEBUG, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries); | 1172 av_log(NULL, AV_LOG_DEBUG, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries); |
1151 #endif | 1173 #endif |
1152 sc->sample_to_chunk_sz = entries; | 1174 sc->sample_to_chunk_sz = entries; |
1153 sc->sample_to_chunk = (MOV_sample_to_chunk_tbl*) av_malloc(entries * sizeof(MOV_sample_to_chunk_tbl)); | 1175 sc->sample_to_chunk = (MOV_sample_to_chunk_tbl*) av_malloc(entries * sizeof(MOV_sample_to_chunk_tbl)); |
1166 | 1188 |
1167 static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) | 1189 static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) |
1168 { | 1190 { |
1169 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; | 1191 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; |
1170 MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; | 1192 MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; |
1171 int entries, i; | 1193 unsigned int i, entries; |
1172 | 1194 |
1173 print_atom("stss", atom); | 1195 print_atom("stss", atom); |
1174 | 1196 |
1175 get_byte(pb); /* version */ | 1197 get_byte(pb); /* version */ |
1176 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ | 1198 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ |
1177 | 1199 |
1178 entries = get_be32(pb); | 1200 entries = get_be32(pb); |
1201 | |
1202 if(entries >= UINT_MAX / sizeof(long)) | |
1203 return -1; | |
1204 | |
1179 sc->keyframe_count = entries; | 1205 sc->keyframe_count = entries; |
1180 #ifdef DEBUG | 1206 #ifdef DEBUG |
1181 av_log(NULL, AV_LOG_DEBUG, "keyframe_count = %ld\n", sc->keyframe_count); | 1207 av_log(NULL, AV_LOG_DEBUG, "keyframe_count = %ld\n", sc->keyframe_count); |
1182 #endif | 1208 #endif |
1183 sc->keyframes = (long*) av_malloc(entries * sizeof(long)); | 1209 sc->keyframes = (long*) av_malloc(entries * sizeof(long)); |
1194 | 1220 |
1195 static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) | 1221 static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) |
1196 { | 1222 { |
1197 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; | 1223 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; |
1198 MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; | 1224 MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; |
1199 int entries, i; | 1225 unsigned int i, entries; |
1200 | 1226 |
1201 print_atom("stsz", atom); | 1227 print_atom("stsz", atom); |
1202 | 1228 |
1203 get_byte(pb); /* version */ | 1229 get_byte(pb); /* version */ |
1204 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ | 1230 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ |
1205 | 1231 |
1206 sc->sample_size = get_be32(pb); | 1232 sc->sample_size = get_be32(pb); |
1207 entries = get_be32(pb); | 1233 entries = get_be32(pb); |
1234 if(entries >= UINT_MAX / sizeof(long)) | |
1235 return -1; | |
1236 | |
1208 sc->sample_count = entries; | 1237 sc->sample_count = entries; |
1209 #ifdef DEBUG | 1238 #ifdef DEBUG |
1210 av_log(NULL, AV_LOG_DEBUG, "sample_size = %ld sample_count = %ld\n", sc->sample_size, sc->sample_count); | 1239 av_log(NULL, AV_LOG_DEBUG, "sample_size = %ld sample_count = %ld\n", sc->sample_size, sc->sample_count); |
1211 #endif | 1240 #endif |
1212 if(sc->sample_size) | 1241 if(sc->sample_size) |
1225 | 1254 |
1226 static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) | 1255 static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom) |
1227 { | 1256 { |
1228 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; | 1257 AVStream *st = c->fc->streams[c->fc->nb_streams-1]; |
1229 //MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; | 1258 //MOVStreamContext *sc = (MOVStreamContext *)st->priv_data; |
1230 int entries, i; | 1259 unsigned int i, entries; |
1231 int64_t duration=0; | 1260 int64_t duration=0; |
1232 int64_t total_sample_count=0; | 1261 int64_t total_sample_count=0; |
1233 | 1262 |
1234 print_atom("stts", atom); | 1263 print_atom("stts", atom); |
1235 | 1264 |
1236 get_byte(pb); /* version */ | 1265 get_byte(pb); /* version */ |
1237 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ | 1266 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ |
1238 entries = get_be32(pb); | 1267 entries = get_be32(pb); |
1268 if(entries >= UINT_MAX / sizeof(uint64_t)) | |
1269 return -1; | |
1239 | 1270 |
1240 c->streams[c->fc->nb_streams-1]->stts_count = entries; | 1271 c->streams[c->fc->nb_streams-1]->stts_count = entries; |
1241 c->streams[c->fc->nb_streams-1]->stts_data = (uint64_t*) av_malloc(entries * sizeof(uint64_t)); | 1272 c->streams[c->fc->nb_streams-1]->stts_data = (uint64_t*) av_malloc(entries * sizeof(uint64_t)); |
1242 | 1273 |
1243 #ifdef DEBUG | 1274 #ifdef DEBUG |