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

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

Issue 2643123002: MSE: Fix moar mp4 parsing security bugs. (Closed)
Patch Set: Feedback 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"
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 RCHECK(reader->Read1(initialization_vector + i)); 186 RCHECK(reader->Read1(initialization_vector + i));
187 187
188 if (!has_subsamples) { 188 if (!has_subsamples) {
189 subsamples.clear(); 189 subsamples.clear();
190 return true; 190 return true;
191 } 191 }
192 192
193 uint16_t subsample_count; 193 uint16_t subsample_count;
194 RCHECK(reader->Read2(&subsample_count)); 194 RCHECK(reader->Read2(&subsample_count));
195 RCHECK(subsample_count > 0); 195 RCHECK(subsample_count > 0);
196 RCHECK(subsample_count <= subsamples.max_size());
196 subsamples.resize(subsample_count); 197 subsamples.resize(subsample_count);
197 for (SubsampleEntry& subsample : subsamples) { 198 for (SubsampleEntry& subsample : subsamples) {
198 uint16_t clear_bytes; 199 uint16_t clear_bytes;
199 uint32_t cypher_bytes; 200 uint32_t cypher_bytes;
200 RCHECK(reader->Read2(&clear_bytes) && reader->Read4(&cypher_bytes)); 201 RCHECK(reader->Read2(&clear_bytes) && reader->Read4(&cypher_bytes));
201 subsample.clear_bytes = clear_bytes; 202 subsample.clear_bytes = clear_bytes;
202 subsample.cypher_bytes = cypher_bytes; 203 subsample.cypher_bytes = cypher_bytes;
203 } 204 }
204 return true; 205 return true;
205 } 206 }
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 476
476 EditList::EditList() {} 477 EditList::EditList() {}
477 EditList::EditList(const EditList& other) = default; 478 EditList::EditList(const EditList& other) = default;
478 EditList::~EditList() {} 479 EditList::~EditList() {}
479 FourCC EditList::BoxType() const { return FOURCC_ELST; } 480 FourCC EditList::BoxType() const { return FOURCC_ELST; }
480 481
481 bool EditList::Parse(BoxReader* reader) { 482 bool EditList::Parse(BoxReader* reader) {
482 uint32_t count; 483 uint32_t count;
483 RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&count)); 484 RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&count));
484 485
485 if (reader->version() == 1) { 486 const size_t bytes_per_edit = reader->version() == 1 ? 20 : 12;
486 RCHECK(reader->HasBytes(count * 20)); 487
487 } else { 488 // Cast |count| to size_t before multiplying to support maximum platform size.
488 RCHECK(reader->HasBytes(count * 12)); 489 base::CheckedNumeric<size_t> bytes_needed =
489 } 490 base::CheckMul(bytes_per_edit, static_cast<size_t>(count));
491 RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(),
492 "Extreme ELST count exceeds implementation limit.");
493 RCHECK(reader->HasBytes(bytes_needed.ValueOrDie()));
494
495 RCHECK(count <= edits.max_size());
490 edits.resize(count); 496 edits.resize(count);
491 497
492 for (std::vector<EditListEntry>::iterator edit = edits.begin(); 498 for (std::vector<EditListEntry>::iterator edit = edits.begin();
493 edit != edits.end(); ++edit) { 499 edit != edits.end(); ++edit) {
494 if (reader->version() == 1) { 500 if (reader->version() == 1) {
495 RCHECK(reader->Read8(&edit->segment_duration) && 501 RCHECK(reader->Read8(&edit->segment_duration) &&
496 reader->Read8s(&edit->media_time)); 502 reader->Read8s(&edit->media_time));
497 } else { 503 } else {
498 RCHECK(reader->Read4Into8(&edit->segment_duration) && 504 RCHECK(reader->Read4Into8(&edit->segment_duration) &&
499 reader->Read4sInto8s(&edit->media_time)); 505 reader->Read4sInto8s(&edit->media_time));
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 } else { 1131 } else {
1126 data_offset = 0; 1132 data_offset = 0;
1127 } 1133 }
1128 1134
1129 uint32_t first_sample_flags = 0; 1135 uint32_t first_sample_flags = 0;
1130 if (first_sample_flags_present) 1136 if (first_sample_flags_present)
1131 RCHECK(reader->Read4(&first_sample_flags)); 1137 RCHECK(reader->Read4(&first_sample_flags));
1132 1138
1133 int fields = sample_duration_present + sample_size_present + 1139 int fields = sample_duration_present + sample_size_present +
1134 sample_flags_present + sample_composition_time_offsets_present; 1140 sample_flags_present + sample_composition_time_offsets_present;
1141 const size_t bytes_per_field = 4;
1135 1142
1136 // Cast |sample_count| to size_t before multiplying to support maximum 1143 // Cast |sample_count| to size_t before multiplying to support maximum
1137 // platform size. 1144 // platform size.
1138 base::CheckedNumeric<size_t> bytes_needed = 1145 base::CheckedNumeric<size_t> bytes_needed = base::CheckMul(
1139 base::CheckMul(fields, static_cast<size_t>(sample_count)); 1146 fields, bytes_per_field, static_cast<size_t>(sample_count));
1140 RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(), 1147 RCHECK_MEDIA_LOGGED(
1141 "Extreme TRUN sample count exceeds system address space"); 1148 bytes_needed.IsValid(), reader->media_log(),
1149 "Extreme TRUN sample count exceeds implementation limit.");
1142 RCHECK(reader->HasBytes(bytes_needed.ValueOrDie())); 1150 RCHECK(reader->HasBytes(bytes_needed.ValueOrDie()));
1143 1151
1144 if (sample_duration_present) { 1152 if (sample_duration_present) {
1145 RCHECK(sample_count <= sample_durations.max_size()); 1153 RCHECK(sample_count <= sample_durations.max_size());
1146 sample_durations.resize(sample_count); 1154 sample_durations.resize(sample_count);
1147 } 1155 }
1148 if (sample_size_present) { 1156 if (sample_size_present) {
1149 RCHECK(sample_count <= sample_sizes.max_size()); 1157 RCHECK(sample_count <= sample_sizes.max_size());
1150 sample_sizes.resize(sample_count); 1158 sample_sizes.resize(sample_count);
1151 } 1159 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1192 RCHECK(reader->Read4(&grouping_type_parameter)); 1200 RCHECK(reader->Read4(&grouping_type_parameter));
1193 1201
1194 if (grouping_type != FOURCC_SEIG) { 1202 if (grouping_type != FOURCC_SEIG) {
1195 DLOG(WARNING) << "SampleToGroup box with grouping_type '" << grouping_type 1203 DLOG(WARNING) << "SampleToGroup box with grouping_type '" << grouping_type
1196 << "' is not supported."; 1204 << "' is not supported.";
1197 return true; 1205 return true;
1198 } 1206 }
1199 1207
1200 uint32_t count; 1208 uint32_t count;
1201 RCHECK(reader->Read4(&count)); 1209 RCHECK(reader->Read4(&count));
1210
1211 const size_t bytes_per_entry = 8;
1212 // Cast |count| to size_t before multiplying to support maximum platform size.
1213 base::CheckedNumeric<size_t> bytes_needed =
1214 base::CheckMul(bytes_per_entry, static_cast<size_t>(count));
1215 RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(),
1216 "Extreme SBGP count exceeds implementation limit.");
1217 RCHECK(reader->HasBytes(bytes_needed.ValueOrDie()));
1218
1219 RCHECK(count <= entries.max_size());
1202 entries.resize(count); 1220 entries.resize(count);
1203 for (uint32_t i = 0; i < count; ++i) { 1221 for (uint32_t i = 0; i < count; ++i) {
1204 RCHECK(reader->Read4(&entries[i].sample_count) && 1222 RCHECK(reader->Read4(&entries[i].sample_count) &&
1205 reader->Read4(&entries[i].group_description_index)); 1223 reader->Read4(&entries[i].group_description_index));
1206 } 1224 }
1207 return true; 1225 return true;
1208 } 1226 }
1209 1227
1210 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry() 1228 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry()
1211 : is_encrypted(false), 1229 : is_encrypted(false),
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 1290
1273 const size_t kEntrySize = sizeof(uint32_t) + kKeyIdSize; 1291 const size_t kEntrySize = sizeof(uint32_t) + kKeyIdSize;
1274 uint32_t default_length = 0; 1292 uint32_t default_length = 0;
1275 if (version == 1) { 1293 if (version == 1) {
1276 RCHECK(reader->Read4(&default_length)); 1294 RCHECK(reader->Read4(&default_length));
1277 RCHECK(default_length == 0 || default_length >= kEntrySize); 1295 RCHECK(default_length == 0 || default_length >= kEntrySize);
1278 } 1296 }
1279 1297
1280 uint32_t count; 1298 uint32_t count;
1281 RCHECK(reader->Read4(&count)); 1299 RCHECK(reader->Read4(&count));
1300
1301 // Check that we have at least two bytes for each entry before allocating a
1302 // potentially huge entries vector. In reality each entry will require a
1303 // variable number of bytes in excess of 2.
1304 const int bytes_per_entry = 2;
1305 // Cast |count| to size_t before multiplying to support maximum platform size.
1306 base::CheckedNumeric<size_t> bytes_needed =
1307 base::CheckMul(bytes_per_entry, static_cast<size_t>(count));
1308 RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(),
1309 "Extreme SGPD count exceeds implementation limit.");
1310 RCHECK(reader->HasBytes(bytes_needed.ValueOrDie()));
1311
1312 RCHECK(count <= entries.max_size());
1282 entries.resize(count); 1313 entries.resize(count);
1283 for (uint32_t i = 0; i < count; ++i) { 1314 for (uint32_t i = 0; i < count; ++i) {
1284 if (version == 1) { 1315 if (version == 1) {
1285 if (default_length == 0) { 1316 if (default_length == 0) {
1286 uint32_t description_length = 0; 1317 uint32_t description_length = 0;
1287 RCHECK(reader->Read4(&description_length)); 1318 RCHECK(reader->Read4(&description_length));
1288 RCHECK(description_length >= kEntrySize); 1319 RCHECK(description_length >= kEntrySize);
1289 } 1320 }
1290 } 1321 }
1291 RCHECK(entries[i].Parse(reader)); 1322 RCHECK(entries[i].Parse(reader));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1343 IndependentAndDisposableSamples::IndependentAndDisposableSamples( 1374 IndependentAndDisposableSamples::IndependentAndDisposableSamples(
1344 const IndependentAndDisposableSamples& other) = default; 1375 const IndependentAndDisposableSamples& other) = default;
1345 IndependentAndDisposableSamples::~IndependentAndDisposableSamples() {} 1376 IndependentAndDisposableSamples::~IndependentAndDisposableSamples() {}
1346 FourCC IndependentAndDisposableSamples::BoxType() const { return FOURCC_SDTP; } 1377 FourCC IndependentAndDisposableSamples::BoxType() const { return FOURCC_SDTP; }
1347 1378
1348 bool IndependentAndDisposableSamples::Parse(BoxReader* reader) { 1379 bool IndependentAndDisposableSamples::Parse(BoxReader* reader) {
1349 RCHECK(reader->ReadFullBoxHeader()); 1380 RCHECK(reader->ReadFullBoxHeader());
1350 RCHECK(reader->version() == 0); 1381 RCHECK(reader->version() == 0);
1351 RCHECK(reader->flags() == 0); 1382 RCHECK(reader->flags() == 0);
1352 1383
1353 int sample_count = reader->box_size() - reader->pos(); 1384 size_t sample_count = reader->box_size() - reader->pos();
1385 RCHECK(sample_count <= sample_depends_on_.max_size());
1354 sample_depends_on_.resize(sample_count); 1386 sample_depends_on_.resize(sample_count);
1355 for (int i = 0; i < sample_count; ++i) { 1387 for (size_t i = 0; i < sample_count; ++i) {
1356 uint8_t sample_info; 1388 uint8_t sample_info;
1357 RCHECK(reader->Read1(&sample_info)); 1389 RCHECK(reader->Read1(&sample_info));
1358 1390
1359 sample_depends_on_[i] = 1391 sample_depends_on_[i] =
1360 static_cast<SampleDependsOn>((sample_info >> 4) & 0x3); 1392 static_cast<SampleDependsOn>((sample_info >> 4) & 0x3);
1361 1393
1362 RCHECK(sample_depends_on_[i] != kSampleDependsOnReserved); 1394 RCHECK(sample_depends_on_[i] != kSampleDependsOnReserved);
1363 } 1395 }
1364 1396
1365 return true; 1397 return true;
1366 } 1398 }
1367 1399
1368 SampleDependsOn IndependentAndDisposableSamples::sample_depends_on( 1400 SampleDependsOn IndependentAndDisposableSamples::sample_depends_on(
1369 size_t i) const { 1401 size_t i) const {
1370 if (i >= sample_depends_on_.size()) 1402 if (i >= sample_depends_on_.size())
1371 return kSampleDependsOnUnknown; 1403 return kSampleDependsOnUnknown;
1372 1404
1373 return sample_depends_on_[i]; 1405 return sample_depends_on_[i];
1374 } 1406 }
1375 1407
1376 } // namespace mp4 1408 } // namespace mp4
1377 } // namespace media 1409 } // 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