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

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

Issue 2643573003: MSE: Fix Mp4 TRUN parsing overflow (Closed)
Patch Set: Proper unit test for TRUN sample_count overflow 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
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_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
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
OLDNEW
« media/formats/mp4/box_definitions.cc ('K') | « media/formats/mp4/box_definitions.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698