[amlogic-decoder][vp9] Limit video size
These sizes are taken directly from the bitstream, so limit them so we
won't try to create gigantic textures with invalid inputs.
Bug: 41492
Change-Id: Ifffe43fb3fb9254228db35f1a130813bf9453e2e
diff --git a/garnet/drivers/video/amlogic-decoder/tests/integration/test_vp9.cc b/garnet/drivers/video/amlogic-decoder/tests/integration/test_vp9.cc
index 03784a98..02b6e2a 100644
--- a/garnet/drivers/video/amlogic-decoder/tests/integration/test_vp9.cc
+++ b/garnet/drivers/video/amlogic-decoder/tests/integration/test_vp9.cc
@@ -581,8 +581,8 @@
video.reset();
}
- static void DecodeMalformed(const char* input_filename, uint32_t modification_offset,
- uint8_t modification_value) {
+ static void DecodeMalformed(const char* input_filename,
+ const std::vector<std::pair<uint32_t, uint8_t>>& modifications) {
auto video = std::make_unique<AmlogicVideo>();
ASSERT_TRUE(video);
@@ -631,7 +631,9 @@
auto aml_data = ConvertIvfToAmlV(test_ivf->ptr, test_ivf->size);
// Arbitrary modifications to an AMLV header shouldn't happen in production code,
// because the driver is what creates that. The rest is fair game, though.
- aml_data[modification_offset] = modification_value;
+ for (auto& mod : modifications) {
+ aml_data[mod.first] = mod.second;
+ }
EXPECT_EQ(ZX_OK, video->parser()->ParseVideo(aml_data.data(), aml_data.size()));
EXPECT_EQ(std::future_status::ready,
first_wait_valid.get_future().wait_for(std::chrono::seconds(1)));
@@ -694,5 +696,17 @@
TEST(VP9, DecodeMalformedHang) {
// Numbers are essentially random, but picked to ensure the decoder would
// normally hang. The offset should be >= 16 to avoid hitting the AMLV header.
- TestVP9::DecodeMalformed("video_test_data/test-25fps.vp9", 17, 10);
+ TestVP9::DecodeMalformed("video_test_data/test-25fps.vp9", {{17, 10}});
+}
+
+TEST(VP9, DecodeMalformedLarge) {
+ constexpr uint32_t kAmlVHeaderSize = 16;
+ // Modify bits [12, 15] of the width to 0xf (and keep colorspace the same at 0x0).
+ // The width should now be 0xf13f.
+ constexpr uint32_t kWidthModificationOffset = kAmlVHeaderSize + 4;
+ // Modify bits [12, 15] of the height to 0xf (and keep the width the same, since its low 4 bits
+ // are already 0xf). The height should now be 0xf0ef.
+ constexpr uint32_t kHeightModificationOffset = kAmlVHeaderSize + 6;
+ TestVP9::DecodeMalformed("video_test_data/test-25fps.vp9",
+ {{kWidthModificationOffset, 0x0f}, {kHeightModificationOffset, 0xff}});
}
diff --git a/garnet/drivers/video/amlogic-decoder/vp9_decoder.cc b/garnet/drivers/video/amlogic-decoder/vp9_decoder.cc
index 2351535..d783bd0 100644
--- a/garnet/drivers/video/amlogic-decoder/vp9_decoder.cc
+++ b/garnet/drivers/video/amlogic-decoder/vp9_decoder.cc
@@ -1100,6 +1100,14 @@
uint32_t coded_height = fbl::round_up(params->hw_height, 2u);
uint32_t stride = fbl::round_up(params->hw_width, 32u);
+ // Support up to 4kx2k, the hardware limit.
+ constexpr uint32_t kMaxWidth = 4096, kMaxHeight = 2176;
+ if (coded_width > kMaxWidth || coded_height > kMaxHeight) {
+ DECODE_ERROR("Invalid stream size %dx%d\n", coded_width, coded_height);
+ CallErrorHandler();
+ return false;
+ }
+
// If !is_current_output_buffer_collection_usable_, then we don't support dynamic dimensions.
bool buffers_allocated = !!frames_[0]->frame || !!frames_[0]->on_deck_frame;
// For VP9 we have kMinFrames and kMaxFrames as the min/max bounds on # of frames the decoder is