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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: media/formats/mp4/box_reader_unittest.cc
diff --git a/media/formats/mp4/box_reader_unittest.cc b/media/formats/mp4/box_reader_unittest.cc
index 09df3d7f3d36c3f88a5b6da421ff559512435442..b416ab55eebb46b906afff216b2bcb596783d531 100644
--- a/media/formats/mp4/box_reader_unittest.cc
+++ b/media/formats/mp4/box_reader_unittest.cc
@@ -301,21 +301,11 @@ TEST_F(BoxReaderTest, ScanChildrenWithInvalidChild) {
EXPECT_FALSE(reader->ReadChild(&child));
}
-TEST_F(BoxReaderTest, ReadAllChildrenWithInvalidChild) {
chcunningham 2017/01/18 21:13:31 This test was busted. On 32-bit, we overflow when
- // This data is not a valid 'emsg' box. It is just used as a top-level box
- // as ReadTopLevelBox() has a restricted set of boxes it allows.
- // The nested 'trun' box is used as it includes a count of the number
- // of samples. The data specifies a large number of samples, but only 1
- // is actually included in the box. Verifying that the large count does not
- // cause an int32_t overflow which would allow parsing of TrackFragmentRun
- // to read past the end of the buffer.
+TEST_F(BoxReaderTest, ReadAllChildrenWithChildLargerThanParent) {
static const uint8_t kData[] = {
- 0x00, 0x00, 0x00, 0x28, 'e', 'm', 's', 'g', // outer box
- 0x00, 0x00, 0x00, 0x20, 't', 'r', 'u', 'n', // nested box
- 0x00, 0x00, 0x0f, 0x00, // version = 0, flags = samples present
- 0xff, 0xff, 0xff, 0xff, // count = max, but only 1 actually included
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ 0x00, 0x00, 0x00, 0x10, 's', 'k', 'i', 'p', // outer box
+ 0x00, 0x00, 0x00, 0x10, 'p', 's', 's', 'h', // nested box
+ };
bool err;
std::unique_ptr<BoxReader> reader(
@@ -323,19 +313,32 @@ TEST_F(BoxReaderTest, ReadAllChildrenWithInvalidChild) {
EXPECT_FALSE(err);
EXPECT_TRUE(reader);
- EXPECT_EQ(FOURCC_EMSG, reader->type());
+ EXPECT_EQ(FOURCC_SKIP, reader->type());
- // Reading the child should fail since the number of samples specified
- // doesn't match what is in the box.
- std::vector<TrackFragmentRun> children;
- EXPECT_FALSE(reader->ReadAllChildrenAndCheckFourCC(&children));
+ std::vector<PsshBox> tmp;
+ EXPECT_FALSE(reader->ReadAllChildren(&tmp));
}
-TEST_F(BoxReaderTest, ReadAllChildrenWithChildLargerThanParent) {
+TEST_F(BoxReaderTest, TrunSampleCount32bitOverflow) {
+ // This data is not a valid 'emsg' box. It is just used as a top-level box
+ // as ReadTopLevelBox() has a restricted set of boxes it allows.
+ // The nested 'trun' box specifies an unusually high number of samples, though
+ // only one sample is actually included in the box. The values for "sample
+ // count" and "flags" are chosen such that their 32-bit product will overflow
+ // to a very small number (4), leading to incorrect assumptions about bytes
+ // available and ultimately OOB reads. http://crbug.com/679640
static const uint8_t kData[] = {
- 0x00, 0x00, 0x00, 0x10, 's', 'k', 'i', 'p', // outer box
- 0x00, 0x00, 0x00, 0x10, 'p', 's', 's', 'h', // nested box
- };
+ 0x00, 0x00, 0x00, 0x28,
+ 'e', 'm', 's', 'g', // outer box
+ 0x00, 0x00, 0x00, 0x20,
+ 't', 'r', 'u', 'n', // nested box
+ 0x00, 0x00, // version = 0
+ 0x03, 0x00, // flags = 2 fields present (sample duration and sample size)
+ 0x80, 0x00, 0x00, 0x02, // sample count = 2147483650
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, // only one sample present
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00};
bool err;
std::unique_ptr<BoxReader> reader(
@@ -343,10 +346,25 @@ TEST_F(BoxReaderTest, ReadAllChildrenWithChildLargerThanParent) {
EXPECT_FALSE(err);
EXPECT_TRUE(reader);
- EXPECT_EQ(FOURCC_SKIP, reader->type());
+ EXPECT_EQ(FOURCC_EMSG, reader->type());
- std::vector<PsshBox> tmp;
- EXPECT_FALSE(reader->ReadAllChildren(&tmp));
+// Overflow is only triggered/caught on 32-bit systems. 64-bit systems will
+// instead fail parsing because kData does not have enough bytes to describe
+// the large number of samples.
+#if defined(ARCH_CPU_32_BITS)
+ const int kOverflowLogCount = 1;
+#else
+ const int kOverflowLogCount = 0;
+#endif
+
+ EXPECT_MEDIA_LOG(
+ HasSubstr("Extreme TRUN sample count exceeds system address space"))
+ .Times(kOverflowLogCount);
+
+ // Reading the child should fail since the number of samples specified
+ // doesn't match what is in the box.
+ std::vector<TrackFragmentRun> children;
+ EXPECT_FALSE(reader->ReadAllChildrenAndCheckFourCC(&children));
}
} // namespace mp4
« 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