From d35a6865178acf1596ae6674dad894b47c4f0a23 Mon Sep 17 00:00:00 2001 From: Sebastian Jansson Date: Mon, 9 Mar 2020 19:18:14 +0100 Subject: [PATCH] Reland "Fix for out-of-bounds write in square test frame generator." This is a reland of 30026214b13535a9fe1c47f1463378fbf976c643 Original change's description: > Fix for out-of-bounds write in square test frame generator. > > The length is set on construction and includes an assumption on the > image resolution, if the resolution changes, a square might be larger > than what fits into the buffer, causing an out of bounds write. This > CL fixes this simply by restricting the size of the square. > > Bug: webrtc:11415 > Change-Id: Iee14a1971997b4ae2fddef0a7af7c76a2509e879 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170042 > Commit-Queue: Sebastian Jansson > Reviewed-by: Ali Tofigh > Cr-Commit-Position: refs/heads/master@{#30732} Bug: webrtc:11415 Change-Id: I0dc584858208f478434ebc6f9e31634595c4e5ad Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170116 Reviewed-by: Ali Tofigh Commit-Queue: Sebastian Jansson Cr-Commit-Position: refs/heads/master@{#30779} --- test/frame_generator.cc | 20 ++++++++++--------- .../ivf_video_frame_generator_unittest.cc | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/test/frame_generator.cc b/test/frame_generator.cc index e3b4a06596..1f998427ac 100644 --- a/test/frame_generator.cc +++ b/test/frame_generator.cc @@ -116,21 +116,23 @@ void SquareGenerator::Square::Draw( RTC_DCHECK(frame_buffer->type() == VideoFrameBuffer::Type::kI420 || frame_buffer->type() == VideoFrameBuffer::Type::kI420A); rtc::scoped_refptr buffer = frame_buffer->ToI420(); - x_ = (x_ + random_generator_.Rand(0, 4)) % (buffer->width() - length_); - y_ = (y_ + random_generator_.Rand(0, 4)) % (buffer->height() - length_); - for (int y = y_; y < y_ + length_; ++y) { + int length_cap = std::min(buffer->height(), buffer->width()) / 4; + int length = std::min(length_, length_cap); + x_ = (x_ + random_generator_.Rand(0, 4)) % (buffer->width() - length); + y_ = (y_ + random_generator_.Rand(0, 4)) % (buffer->height() - length); + for (int y = y_; y < y_ + length; ++y) { uint8_t* pos_y = (const_cast(buffer->DataY()) + x_ + y * buffer->StrideY()); - memset(pos_y, yuv_y_, length_); + memset(pos_y, yuv_y_, length); } - for (int y = y_; y < y_ + length_; y = y + 2) { + for (int y = y_; y < y_ + length; y = y + 2) { uint8_t* pos_u = (const_cast(buffer->DataU()) + x_ / 2 + y / 2 * buffer->StrideU()); - memset(pos_u, yuv_u_, length_ / 2); + memset(pos_u, yuv_u_, length / 2); uint8_t* pos_v = (const_cast(buffer->DataV()) + x_ / 2 + y / 2 * buffer->StrideV()); - memset(pos_v, yuv_v_, length_ / 2); + memset(pos_v, yuv_v_, length / 2); } if (frame_buffer->type() == VideoFrameBuffer::Type::kI420) @@ -138,10 +140,10 @@ void SquareGenerator::Square::Draw( // Optionally draw on alpha plane if given. const webrtc::I420ABufferInterface* yuva_buffer = frame_buffer->GetI420A(); - for (int y = y_; y < y_ + length_; ++y) { + for (int y = y_; y < y_ + length; ++y) { uint8_t* pos_y = (const_cast(yuva_buffer->DataA()) + x_ + y * yuva_buffer->StrideA()); - memset(pos_y, yuv_a_, length_); + memset(pos_y, yuv_a_, length); } } diff --git a/test/testsupport/ivf_video_frame_generator_unittest.cc b/test/testsupport/ivf_video_frame_generator_unittest.cc index a5e99d1a66..0c364dbb1d 100644 --- a/test/testsupport/ivf_video_frame_generator_unittest.cc +++ b/test/testsupport/ivf_video_frame_generator_unittest.cc @@ -48,7 +48,7 @@ constexpr int kMaxFrameEncodeWaitTimeoutMs = 2000; static const VideoEncoder::Capabilities kCapabilities(false); #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) -constexpr double kExpectedMinPsnr = 36; +constexpr double kExpectedMinPsnr = 35; #else constexpr double kExpectedMinPsnr = 39; #endif