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 |