webm_info,PrintVP9Info: validate alt ref sizes

fixes out of bounds reads with corrupted bitstreams

BUG=webm:1416,webm:1417

Change-Id: Ia643708b4b74d153a7b1dee1c4cbcab7f79d7111
This commit is contained in:
James Zern
2017-04-21 11:59:44 -07:00
parent 9b97ca197d
commit 85f7e2e428
4 changed files with 34 additions and 0 deletions

View File

@@ -59,6 +59,18 @@ class Vp9HeaderParserTests : public ::testing::Test {
CreateAndLoadSegment(filename, 4); CreateAndLoadSegment(filename, 4);
} }
// Load a corrupted segment with no expectation of correctness.
void CreateAndLoadInvalidSegment(const std::string& filename) {
filename_ = test::GetTestFilePath(filename);
ASSERT_EQ(0, reader_.Open(filename_.c_str()));
is_reader_open_ = true;
pos_ = 0;
mkvparser::EBMLHeader ebml_header;
ebml_header.Parse(&reader_, pos_);
ASSERT_EQ(0, mkvparser::Segment::CreateInstance(&reader_, pos_, segment_));
ASSERT_GE(0, segment_->Load());
}
void ProcessTheFrames(bool invalid_bitstream) { void ProcessTheFrames(bool invalid_bitstream) {
unsigned char* data = NULL; unsigned char* data = NULL;
size_t data_len = 0; size_t data_len = 0;
@@ -137,6 +149,22 @@ TEST_F(Vp9HeaderParserTests, Muxed) {
EXPECT_EQ(1, parser_.frame_parallel_mode()); EXPECT_EQ(1, parser_.frame_parallel_mode());
} }
TEST_F(Vp9HeaderParserTests, Invalid) {
const char* files[] = {
"invalid/invalid_vp9_bitstream-bug_1416.webm",
"invalid/invalid_vp9_bitstream-bug_1417.webm",
};
for (int i = 0; i < static_cast<int>(sizeof(files) / sizeof(files[0])); ++i) {
SCOPED_TRACE(files[i]);
ASSERT_NO_FATAL_FAILURE(CreateAndLoadInvalidSegment(files[i]));
ProcessTheFrames(true);
CloseReader();
delete segment_;
segment_ = NULL;
}
}
} // namespace } // namespace
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {

Binary file not shown.

Binary file not shown.

View File

@@ -709,6 +709,12 @@ void PrintVP9Info(const uint8_t* data, int size, FILE* o, int64_t time_ns,
do { do {
const size_t frame_length = (count > 0) ? sizes[i] : size; const size_t frame_length = (count > 0) ? sizes[i] : size;
if (frame_length > std::numeric_limits<int>::max() ||
static_cast<int>(frame_length) > size) {
fprintf(o, " invalid VP9 frame size (%u)\n",
static_cast<uint32_t>(frame_length));
return;
}
parser->SetFrame(data, frame_length); parser->SetFrame(data, frame_length);
parser->ParseUncompressedHeader(); parser->ParseUncompressedHeader();
level_stats->AddFrame(*parser, time_ns); level_stats->AddFrame(*parser, time_ns);