Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: media/formats/mp4/box_definitions.cc

Issue 2654913002: [TO 56] Fix mp4 parsing security bugs. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | media/formats/mp4/box_reader_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/formats/mp4/box_definitions.h" 5 #include "media/formats/mp4/box_definitions.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/numerics/safe_math.h"
12 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
13 #include "media/base/media_switches.h" 14 #include "media/base/media_switches.h"
14 #include "media/base/video_types.h" 15 #include "media/base/video_types.h"
15 #include "media/base/video_util.h" 16 #include "media/base/video_util.h"
16 #include "media/filters/h264_parser.h" 17 #include "media/filters/h264_parser.h"
17 #include "media/formats/mp4/avc.h" 18 #include "media/formats/mp4/avc.h"
18 #include "media/formats/mp4/es_descriptor.h" 19 #include "media/formats/mp4/es_descriptor.h"
19 #include "media/formats/mp4/rcheck.h" 20 #include "media/formats/mp4/rcheck.h"
20 #include "media/media_features.h" 21 #include "media/media_features.h"
21 22
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 const SampleAuxiliaryInformationOffset& other) = default; 111 const SampleAuxiliaryInformationOffset& other) = default;
111 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() {} 112 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() {}
112 FourCC SampleAuxiliaryInformationOffset::BoxType() const { return FOURCC_SAIO; } 113 FourCC SampleAuxiliaryInformationOffset::BoxType() const { return FOURCC_SAIO; }
113 114
114 bool SampleAuxiliaryInformationOffset::Parse(BoxReader* reader) { 115 bool SampleAuxiliaryInformationOffset::Parse(BoxReader* reader) {
115 RCHECK(reader->ReadFullBoxHeader()); 116 RCHECK(reader->ReadFullBoxHeader());
116 if (reader->flags() & 1) 117 if (reader->flags() & 1)
117 RCHECK(reader->SkipBytes(8)); 118 RCHECK(reader->SkipBytes(8));
118 119
119 uint32_t count; 120 uint32_t count;
120 RCHECK(reader->Read4(&count) && 121 RCHECK(reader->Read4(&count));
121 reader->HasBytes(count * (reader->version() == 1 ? 8 : 4))); 122 int bytes_per_offset = reader->version() == 1 ? 8 : 4;
123
124 base::CheckedNumeric<size_t> bytes_needed =
125 base::CheckedNumeric<size_t>(bytes_per_offset);
126 bytes_needed *= count;
127 RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(),
128 "Extreme SAIO count exceeds implementation limit.");
129 RCHECK(reader->HasBytes(bytes_needed.ValueOrDie()));
130
131 RCHECK(count <= offsets.max_size());
122 offsets.resize(count); 132 offsets.resize(count);
123 133
124 for (uint32_t i = 0; i < count; i++) { 134 for (uint32_t i = 0; i < count; i++) {
125 if (reader->version() == 1) { 135 if (reader->version() == 1) {
126 RCHECK(reader->Read8(&offsets[i])); 136 RCHECK(reader->Read8(&offsets[i]));
127 } else { 137 } else {
128 RCHECK(reader->Read4Into8(&offsets[i])); 138 RCHECK(reader->Read4Into8(&offsets[i]));
129 } 139 }
130 } 140 }
131 return true; 141 return true;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 RCHECK(reader->Read1(initialization_vector + i)); 178 RCHECK(reader->Read1(initialization_vector + i));
169 179
170 if (!has_subsamples) { 180 if (!has_subsamples) {
171 subsamples.clear(); 181 subsamples.clear();
172 return true; 182 return true;
173 } 183 }
174 184
175 uint16_t subsample_count; 185 uint16_t subsample_count;
176 RCHECK(reader->Read2(&subsample_count)); 186 RCHECK(reader->Read2(&subsample_count));
177 RCHECK(subsample_count > 0); 187 RCHECK(subsample_count > 0);
188 RCHECK(subsample_count <= subsamples.max_size());
178 subsamples.resize(subsample_count); 189 subsamples.resize(subsample_count);
179 for (SubsampleEntry& subsample : subsamples) { 190 for (SubsampleEntry& subsample : subsamples) {
180 uint16_t clear_bytes; 191 uint16_t clear_bytes;
181 uint32_t cypher_bytes; 192 uint32_t cypher_bytes;
182 RCHECK(reader->Read2(&clear_bytes) && reader->Read4(&cypher_bytes)); 193 RCHECK(reader->Read2(&clear_bytes) && reader->Read4(&cypher_bytes));
183 subsample.clear_bytes = clear_bytes; 194 subsample.clear_bytes = clear_bytes;
184 subsample.cypher_bytes = cypher_bytes; 195 subsample.cypher_bytes = cypher_bytes;
185 } 196 }
186 return true; 197 return true;
187 } 198 }
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 432
422 EditList::EditList() {} 433 EditList::EditList() {}
423 EditList::EditList(const EditList& other) = default; 434 EditList::EditList(const EditList& other) = default;
424 EditList::~EditList() {} 435 EditList::~EditList() {}
425 FourCC EditList::BoxType() const { return FOURCC_ELST; } 436 FourCC EditList::BoxType() const { return FOURCC_ELST; }
426 437
427 bool EditList::Parse(BoxReader* reader) { 438 bool EditList::Parse(BoxReader* reader) {
428 uint32_t count; 439 uint32_t count;
429 RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&count)); 440 RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&count));
430 441
431 if (reader->version() == 1) { 442 const size_t bytes_per_edit = reader->version() == 1 ? 20 : 12;
432 RCHECK(reader->HasBytes(count * 20)); 443
433 } else { 444 base::CheckedNumeric<size_t> bytes_needed =
434 RCHECK(reader->HasBytes(count * 12)); 445 base::CheckedNumeric<size_t>(bytes_per_edit);
435 } 446 bytes_needed *= count;
447 RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(),
448 "Extreme ELST count exceeds implementation limit.");
449 RCHECK(reader->HasBytes(bytes_needed.ValueOrDie()));
450
451 RCHECK(count <= edits.max_size());
436 edits.resize(count); 452 edits.resize(count);
437 453
438 for (std::vector<EditListEntry>::iterator edit = edits.begin(); 454 for (std::vector<EditListEntry>::iterator edit = edits.begin();
439 edit != edits.end(); ++edit) { 455 edit != edits.end(); ++edit) {
440 if (reader->version() == 1) { 456 if (reader->version() == 1) {
441 RCHECK(reader->Read8(&edit->segment_duration) && 457 RCHECK(reader->Read8(&edit->segment_duration) &&
442 reader->Read8s(&edit->media_time)); 458 reader->Read8s(&edit->media_time));
443 } else { 459 } else {
444 RCHECK(reader->Read4Into8(&edit->segment_duration) && 460 RCHECK(reader->Read4Into8(&edit->segment_duration) &&
445 reader->Read4sInto8s(&edit->media_time)); 461 reader->Read4sInto8s(&edit->media_time));
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 } else { 1090 } else {
1075 data_offset = 0; 1091 data_offset = 0;
1076 } 1092 }
1077 1093
1078 uint32_t first_sample_flags = 0; 1094 uint32_t first_sample_flags = 0;
1079 if (first_sample_flags_present) 1095 if (first_sample_flags_present)
1080 RCHECK(reader->Read4(&first_sample_flags)); 1096 RCHECK(reader->Read4(&first_sample_flags));
1081 1097
1082 int fields = sample_duration_present + sample_size_present + 1098 int fields = sample_duration_present + sample_size_present +
1083 sample_flags_present + sample_composition_time_offsets_present; 1099 sample_flags_present + sample_composition_time_offsets_present;
1084 RCHECK(reader->HasBytes(fields * sample_count)); 1100 const size_t bytes_per_field = 4;
1085 1101
1086 if (sample_duration_present) 1102 base::CheckedNumeric<size_t> bytes_needed(fields);
1103 bytes_needed *= bytes_per_field;
1104 bytes_needed *= sample_count;
1105 RCHECK_MEDIA_LOGGED(
1106 bytes_needed.IsValid(), reader->media_log(),
1107 "Extreme TRUN sample count exceeds implementation limit.");
1108 RCHECK(reader->HasBytes(bytes_needed.ValueOrDie()));
1109
1110 if (sample_duration_present) {
1111 RCHECK(sample_count <= sample_durations.max_size());
1087 sample_durations.resize(sample_count); 1112 sample_durations.resize(sample_count);
1088 if (sample_size_present) 1113 }
1114 if (sample_size_present) {
1115 RCHECK(sample_count <= sample_sizes.max_size());
1089 sample_sizes.resize(sample_count); 1116 sample_sizes.resize(sample_count);
1090 if (sample_flags_present) 1117 }
1118 if (sample_flags_present) {
1119 RCHECK(sample_count <= sample_flags.max_size());
1091 sample_flags.resize(sample_count); 1120 sample_flags.resize(sample_count);
1092 if (sample_composition_time_offsets_present) 1121 }
1122 if (sample_composition_time_offsets_present) {
1123 RCHECK(sample_count <= sample_composition_time_offsets.max_size());
1093 sample_composition_time_offsets.resize(sample_count); 1124 sample_composition_time_offsets.resize(sample_count);
1125 }
1094 1126
1095 for (uint32_t i = 0; i < sample_count; ++i) { 1127 for (uint32_t i = 0; i < sample_count; ++i) {
1096 if (sample_duration_present) 1128 if (sample_duration_present)
1097 RCHECK(reader->Read4(&sample_durations[i])); 1129 RCHECK(reader->Read4(&sample_durations[i]));
1098 if (sample_size_present) 1130 if (sample_size_present)
1099 RCHECK(reader->Read4(&sample_sizes[i])); 1131 RCHECK(reader->Read4(&sample_sizes[i]));
1100 if (sample_flags_present) 1132 if (sample_flags_present)
1101 RCHECK(reader->Read4(&sample_flags[i])); 1133 RCHECK(reader->Read4(&sample_flags[i]));
1102 if (sample_composition_time_offsets_present) 1134 if (sample_composition_time_offsets_present)
1103 RCHECK(reader->Read4s(&sample_composition_time_offsets[i])); 1135 RCHECK(reader->Read4s(&sample_composition_time_offsets[i]));
(...skipping 22 matching lines...) Expand all
1126 RCHECK(reader->Read4(&grouping_type_parameter)); 1158 RCHECK(reader->Read4(&grouping_type_parameter));
1127 1159
1128 if (grouping_type != FOURCC_SEIG) { 1160 if (grouping_type != FOURCC_SEIG) {
1129 DLOG(WARNING) << "SampleToGroup box with grouping_type '" << grouping_type 1161 DLOG(WARNING) << "SampleToGroup box with grouping_type '" << grouping_type
1130 << "' is not supported."; 1162 << "' is not supported.";
1131 return true; 1163 return true;
1132 } 1164 }
1133 1165
1134 uint32_t count; 1166 uint32_t count;
1135 RCHECK(reader->Read4(&count)); 1167 RCHECK(reader->Read4(&count));
1168
1169 const size_t bytes_per_entry = 8;
1170 base::CheckedNumeric<size_t> bytes_needed =
1171 base::CheckedNumeric<size_t>(bytes_per_entry);
1172 bytes_needed *= count;
1173 RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(),
1174 "Extreme SBGP count exceeds implementation limit.");
1175 RCHECK(reader->HasBytes(bytes_needed.ValueOrDie()));
1176
1177 RCHECK(count <= entries.max_size());
1136 entries.resize(count); 1178 entries.resize(count);
1137 for (uint32_t i = 0; i < count; ++i) { 1179 for (uint32_t i = 0; i < count; ++i) {
1138 RCHECK(reader->Read4(&entries[i].sample_count) && 1180 RCHECK(reader->Read4(&entries[i].sample_count) &&
1139 reader->Read4(&entries[i].group_description_index)); 1181 reader->Read4(&entries[i].group_description_index));
1140 } 1182 }
1141 return true; 1183 return true;
1142 } 1184 }
1143 1185
1144 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry() 1186 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry()
1145 : is_encrypted(false), iv_size(0) {} 1187 : is_encrypted(false), iv_size(0) {}
(...skipping 22 matching lines...) Expand all
1168 const size_t kKeyIdSize = 16; 1210 const size_t kKeyIdSize = 16;
1169 const size_t kEntrySize = sizeof(uint32_t) + kKeyIdSize; 1211 const size_t kEntrySize = sizeof(uint32_t) + kKeyIdSize;
1170 uint32_t default_length = 0; 1212 uint32_t default_length = 0;
1171 if (version == 1) { 1213 if (version == 1) {
1172 RCHECK(reader->Read4(&default_length)); 1214 RCHECK(reader->Read4(&default_length));
1173 RCHECK(default_length == 0 || default_length >= kEntrySize); 1215 RCHECK(default_length == 0 || default_length >= kEntrySize);
1174 } 1216 }
1175 1217
1176 uint32_t count; 1218 uint32_t count;
1177 RCHECK(reader->Read4(&count)); 1219 RCHECK(reader->Read4(&count));
1220
1221 // Check that we have at least two bytes for each entry before allocating a
1222 // potentially huge entries vector. In reality each entry will require a
1223 // variable number of bytes in excess of 2.
1224 const int bytes_per_entry = 2;
1225 base::CheckedNumeric<size_t> bytes_needed =
1226 base::CheckedNumeric<size_t>(bytes_per_entry);
1227 bytes_needed *= count;
1228 RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(),
1229 "Extreme SGPD count exceeds implementation limit.");
1230 RCHECK(reader->HasBytes(bytes_needed.ValueOrDie()));
1231
1232 RCHECK(count <= entries.max_size());
1178 entries.resize(count); 1233 entries.resize(count);
1179 for (uint32_t i = 0; i < count; ++i) { 1234 for (uint32_t i = 0; i < count; ++i) {
1180 if (version == 1) { 1235 if (version == 1) {
1181 if (default_length == 0) { 1236 if (default_length == 0) {
1182 uint32_t description_length = 0; 1237 uint32_t description_length = 0;
1183 RCHECK(reader->Read4(&description_length)); 1238 RCHECK(reader->Read4(&description_length));
1184 RCHECK(description_length >= kEntrySize); 1239 RCHECK(description_length >= kEntrySize);
1185 } 1240 }
1186 } 1241 }
1187 1242
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1251 IndependentAndDisposableSamples::IndependentAndDisposableSamples( 1306 IndependentAndDisposableSamples::IndependentAndDisposableSamples(
1252 const IndependentAndDisposableSamples& other) = default; 1307 const IndependentAndDisposableSamples& other) = default;
1253 IndependentAndDisposableSamples::~IndependentAndDisposableSamples() {} 1308 IndependentAndDisposableSamples::~IndependentAndDisposableSamples() {}
1254 FourCC IndependentAndDisposableSamples::BoxType() const { return FOURCC_SDTP; } 1309 FourCC IndependentAndDisposableSamples::BoxType() const { return FOURCC_SDTP; }
1255 1310
1256 bool IndependentAndDisposableSamples::Parse(BoxReader* reader) { 1311 bool IndependentAndDisposableSamples::Parse(BoxReader* reader) {
1257 RCHECK(reader->ReadFullBoxHeader()); 1312 RCHECK(reader->ReadFullBoxHeader());
1258 RCHECK(reader->version() == 0); 1313 RCHECK(reader->version() == 0);
1259 RCHECK(reader->flags() == 0); 1314 RCHECK(reader->flags() == 0);
1260 1315
1261 int sample_count = reader->box_size() - reader->pos(); 1316 size_t sample_count = reader->box_size() - reader->pos();
1317 RCHECK(sample_count <= sample_depends_on_.max_size());
1262 sample_depends_on_.resize(sample_count); 1318 sample_depends_on_.resize(sample_count);
1263 for (int i = 0; i < sample_count; ++i) { 1319 for (size_t i = 0; i < sample_count; ++i) {
1264 uint8_t sample_info; 1320 uint8_t sample_info;
1265 RCHECK(reader->Read1(&sample_info)); 1321 RCHECK(reader->Read1(&sample_info));
1266 1322
1267 sample_depends_on_[i] = 1323 sample_depends_on_[i] =
1268 static_cast<SampleDependsOn>((sample_info >> 4) & 0x3); 1324 static_cast<SampleDependsOn>((sample_info >> 4) & 0x3);
1269 1325
1270 RCHECK(sample_depends_on_[i] != kSampleDependsOnReserved); 1326 RCHECK(sample_depends_on_[i] != kSampleDependsOnReserved);
1271 } 1327 }
1272 1328
1273 return true; 1329 return true;
1274 } 1330 }
1275 1331
1276 SampleDependsOn IndependentAndDisposableSamples::sample_depends_on( 1332 SampleDependsOn IndependentAndDisposableSamples::sample_depends_on(
1277 size_t i) const { 1333 size_t i) const {
1278 if (i >= sample_depends_on_.size()) 1334 if (i >= sample_depends_on_.size())
1279 return kSampleDependsOnUnknown; 1335 return kSampleDependsOnUnknown;
1280 1336
1281 return sample_depends_on_[i]; 1337 return sample_depends_on_[i];
1282 } 1338 }
1283 1339
1284 } // namespace mp4 1340 } // namespace mp4
1285 } // namespace media 1341 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | media/formats/mp4/box_reader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698