Chromium Code Reviews| OLD | NEW |
|---|---|
| 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_reader.h" | 5 #include "media/formats/mp4/box_reader.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 294 EXPECT_TRUE(reader); | 294 EXPECT_TRUE(reader); |
| 295 EXPECT_EQ(FOURCC_EMSG, reader->type()); | 295 EXPECT_EQ(FOURCC_EMSG, reader->type()); |
| 296 EXPECT_TRUE(reader->ScanChildren()); | 296 EXPECT_TRUE(reader->ScanChildren()); |
| 297 | 297 |
| 298 // 'elst' specifies lots of EditListEntry's but only includes 1. Thus | 298 // 'elst' specifies lots of EditListEntry's but only includes 1. Thus |
| 299 // parsing it should fail. | 299 // parsing it should fail. |
| 300 EditList child; | 300 EditList child; |
| 301 EXPECT_FALSE(reader->ReadChild(&child)); | 301 EXPECT_FALSE(reader->ReadChild(&child)); |
| 302 } | 302 } |
| 303 | 303 |
| 304 TEST_F(BoxReaderTest, ReadAllChildrenWithInvalidChild) { | 304 TEST_F(BoxReaderTest, ReadAllChildrenWithChildLargerThanParent) { |
|
chcunningham
2017/01/18 21:13:31
This test was busted. On 32-bit, we overflow when
| |
| 305 // This data is not a valid 'emsg' box. It is just used as a top-level box | |
| 306 // as ReadTopLevelBox() has a restricted set of boxes it allows. | |
| 307 // The nested 'trun' box is used as it includes a count of the number | |
| 308 // of samples. The data specifies a large number of samples, but only 1 | |
| 309 // is actually included in the box. Verifying that the large count does not | |
| 310 // cause an int32_t overflow which would allow parsing of TrackFragmentRun | |
| 311 // to read past the end of the buffer. | |
| 312 static const uint8_t kData[] = { | 305 static const uint8_t kData[] = { |
| 313 0x00, 0x00, 0x00, 0x28, 'e', 'm', 's', 'g', // outer box | 306 0x00, 0x00, 0x00, 0x10, 's', 'k', 'i', 'p', // outer box |
| 314 0x00, 0x00, 0x00, 0x20, 't', 'r', 'u', 'n', // nested box | 307 0x00, 0x00, 0x00, 0x10, 'p', 's', 's', 'h', // nested box |
| 315 0x00, 0x00, 0x0f, 0x00, // version = 0, flags = samples present | 308 }; |
| 316 0xff, 0xff, 0xff, 0xff, // count = max, but only 1 actually included | |
| 317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | |
| 319 | 309 |
| 320 bool err; | 310 bool err; |
| 321 std::unique_ptr<BoxReader> reader( | 311 std::unique_ptr<BoxReader> reader( |
| 322 BoxReader::ReadTopLevelBox(kData, sizeof(kData), media_log_, &err)); | 312 BoxReader::ReadTopLevelBox(kData, sizeof(kData), media_log_, &err)); |
| 323 | 313 |
| 324 EXPECT_FALSE(err); | 314 EXPECT_FALSE(err); |
| 325 EXPECT_TRUE(reader); | 315 EXPECT_TRUE(reader); |
| 326 EXPECT_EQ(FOURCC_EMSG, reader->type()); | 316 EXPECT_EQ(FOURCC_SKIP, reader->type()); |
| 327 | 317 |
| 328 // Reading the child should fail since the number of samples specified | 318 std::vector<PsshBox> tmp; |
| 329 // doesn't match what is in the box. | 319 EXPECT_FALSE(reader->ReadAllChildren(&tmp)); |
| 330 std::vector<TrackFragmentRun> children; | |
| 331 EXPECT_FALSE(reader->ReadAllChildrenAndCheckFourCC(&children)); | |
| 332 } | 320 } |
| 333 | 321 |
| 334 TEST_F(BoxReaderTest, ReadAllChildrenWithChildLargerThanParent) { | 322 TEST_F(BoxReaderTest, TrunSampleCount32bitOverflow) { |
| 323 // This data is not a valid 'emsg' box. It is just used as a top-level box | |
| 324 // as ReadTopLevelBox() has a restricted set of boxes it allows. | |
| 325 // The nested 'trun' box specifies an unusually high number of samples, though | |
| 326 // only one sample is actually included in the box. The values for "sample | |
| 327 // count" and "flags" are chosen such that their 32-bit product will overflow | |
| 328 // to a very small number (4), leading to incorrect assumptions about bytes | |
| 329 // available and ultimately OOB reads. http://crbug.com/679640 | |
| 335 static const uint8_t kData[] = { | 330 static const uint8_t kData[] = { |
| 336 0x00, 0x00, 0x00, 0x10, 's', 'k', 'i', 'p', // outer box | 331 0x00, 0x00, 0x00, 0x28, |
| 337 0x00, 0x00, 0x00, 0x10, 'p', 's', 's', 'h', // nested box | 332 'e', 'm', 's', 'g', // outer box |
| 338 }; | 333 0x00, 0x00, 0x00, 0x20, |
| 334 't', 'r', 'u', 'n', // nested box | |
| 335 0x00, 0x00, // version = 0 | |
| 336 0x03, 0x00, // flags = 2 fields present (sample duration and sample size) | |
| 337 0x80, 0x00, 0x00, 0x02, // sample count = 2147483650 | |
| 338 0x00, 0x00, 0x00, 0x00, | |
| 339 0x00, 0x00, 0x00, 0x00, // only one sample present | |
| 340 0x00, 0x00, 0x00, 0x00, | |
| 341 0x00, 0x00, 0x00, 0x00}; | |
| 339 | 342 |
| 340 bool err; | 343 bool err; |
| 341 std::unique_ptr<BoxReader> reader( | 344 std::unique_ptr<BoxReader> reader( |
| 342 BoxReader::ReadTopLevelBox(kData, sizeof(kData), media_log_, &err)); | 345 BoxReader::ReadTopLevelBox(kData, sizeof(kData), media_log_, &err)); |
| 343 | 346 |
| 344 EXPECT_FALSE(err); | 347 EXPECT_FALSE(err); |
| 345 EXPECT_TRUE(reader); | 348 EXPECT_TRUE(reader); |
| 346 EXPECT_EQ(FOURCC_SKIP, reader->type()); | 349 EXPECT_EQ(FOURCC_EMSG, reader->type()); |
| 347 | 350 |
| 348 std::vector<PsshBox> tmp; | 351 // Overflow is only triggered/caught on 32-bit systems. 64-bit systems will |
| 349 EXPECT_FALSE(reader->ReadAllChildren(&tmp)); | 352 // instead fail parsing because kData does not have enough bytes to describe |
| 353 // the large number of samples. | |
| 354 #if defined(ARCH_CPU_32_BITS) | |
| 355 const int kOverflowLogCount = 1; | |
| 356 #else | |
| 357 const int kOverflowLogCount = 0; | |
| 358 #endif | |
| 359 | |
| 360 EXPECT_MEDIA_LOG( | |
| 361 HasSubstr("Extreme TRUN sample count exceeds system address space")) | |
| 362 .Times(kOverflowLogCount); | |
| 363 | |
| 364 // Reading the child should fail since the number of samples specified | |
| 365 // doesn't match what is in the box. | |
| 366 std::vector<TrackFragmentRun> children; | |
| 367 EXPECT_FALSE(reader->ReadAllChildrenAndCheckFourCC(&children)); | |
| 350 } | 368 } |
| 351 | 369 |
| 352 } // namespace mp4 | 370 } // namespace mp4 |
| 353 } // namespace media | 371 } // namespace media |
| OLD | NEW |