Correct vin/vout buffer sizes in ANY21CT

Tested:
libyuv_unittest --gtest_filter=LibYUVConvertTest.P010ToARGBMatrixFilterOverflow
libyuv_unittest --gtest_filter=LibYUVConvertTest.P210ToARGBMatrixFilterOverflow
libyuv_unittest --gtest_filter=LibYUVConvertTest.P010ToAR30MatrixFilterOverflow
libyuv_unittest --gtest_filter=LibYUVConvertTest.P210ToAR30MatrixFilterOverflow

Bug: chromium:543078936
Change-Id: I7001c21d3ef9f7a01bf884332ea6ccbdfd7a69d0
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8229574
Commit-Queue: Wan-Teh Chang <wtc@google.com>
Reviewed-by: Frank Barchard <fbarchard@google.com>
This commit is contained in:
Wan-Teh Chang 2026-08-10 12:15:57 -07:00 committed by libyuv-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 60c4b08950
commit e2a1744681
2 changed files with 83 additions and 3 deletions

View File

@ -834,8 +834,12 @@ ANY21C(NV12ToRGB565Row_Any_LASX, NV12ToRGB565Row_LASX, 1, 1, 2, 2, 15)
#define ANY21CT(NAMEANY, ANY_SIMD, UVSHIFT, DUVSHIFT, T, SBPP, BPP, MASK) \
void NAMEANY(const T* y_buf, const T* uv_buf, uint8_t* dst_ptr, \
const struct YuvConstants* yuvconstants, int width) { \
SIMD_ALIGNED(T vin[16 * 2]); \
SIMD_ALIGNED(T vin[32 * 2]); \
static_assert(SS(MASK + 1, UVSHIFT) * SBPP * 2 <= sizeof(vin) / 2, \
"vin buffer too small"); \
SIMD_ALIGNED(uint8_t vout[64]); \
static_assert(SS(MASK + 1, DUVSHIFT) * BPP <= sizeof(vout), \
"vout buffer too small"); \
memset(vin, 0, sizeof(vin)); /* for msan */ \
int r = width & MASK; \
int n = width & ~MASK; \
@ -844,8 +848,8 @@ ANY21C(NV12ToRGB565Row_Any_LASX, NV12ToRGB565Row_LASX, 1, 1, 2, 2, 15)
} \
ptrdiff_t np = n; \
memcpy(vin, y_buf + np, r * SBPP); \
memcpy(vin + 16, uv_buf + 2 * (np >> UVSHIFT), SS(r, UVSHIFT) * SBPP * 2); \
ANY_SIMD(vin, vin + 16, vout, yuvconstants, MASK + 1); \
memcpy(vin + 32, uv_buf + 2 * (np >> UVSHIFT), SS(r, UVSHIFT) * SBPP * 2); \
ANY_SIMD(vin, vin + 32, vout, yuvconstants, MASK + 1); \
memcpy(dst_ptr + (np >> DUVSHIFT) * BPP, vout, SS(r, DUVSHIFT) * BPP); \
}

View File

@ -2736,6 +2736,82 @@ TEST_F(LibYUVConvertTest, TestUYVYToARGB) {
#endif
}
// Call P010ToARGBMatrixFilter() with a width that is not a multiple of 16.
// Verify there is no stack buffer overflow in P410ToARGBRow_Any_AVX2().
TEST_F(LibYUVConvertTest, P010ToARGBMatrixFilterOverflow) {
int width = 1024 + 15; // 1039
int height = 4;
int dst_stride_argb = width * 4;
align_buffer_page_end_16(src_y, width * height);
align_buffer_page_end_16(src_uv, width * ((height + 1) / 2));
align_buffer_page_end(dst_argb, dst_stride_argb * height);
memset(src_y, 0x02, width * height * sizeof(uint16_t));
memset(src_uv, 0x02, width * ((height + 1) / 2) * sizeof(uint16_t));
EXPECT_EQ(0, P010ToARGBMatrixFilter(src_y, width, src_uv, width, dst_argb,
dst_stride_argb, &kYuvI601Constants,
width, height, kFilterBilinear));
free_aligned_buffer_page_end_16(src_y);
free_aligned_buffer_page_end_16(src_uv);
free_aligned_buffer_page_end(dst_argb);
}
// Call P210ToARGBMatrixFilter() with a width that is not a multiple of 16.
// Verify there is no stack buffer overflow in P410ToARGBRow_Any_AVX2().
TEST_F(LibYUVConvertTest, P210ToARGBMatrixFilterOverflow) {
int width = 1024 + 15; // 1039
int height = 4;
int dst_stride_argb = width * 4;
align_buffer_page_end_16(src_y, width * height);
align_buffer_page_end_16(src_uv, width * height);
align_buffer_page_end(dst_argb, dst_stride_argb * height);
memset(src_y, 0x02, width * height * sizeof(uint16_t));
memset(src_uv, 0x02, width * height * sizeof(uint16_t));
EXPECT_EQ(0, P210ToARGBMatrixFilter(src_y, width, src_uv, width, dst_argb,
dst_stride_argb, &kYuvI601Constants,
width, height, kFilterBilinear));
free_aligned_buffer_page_end_16(src_y);
free_aligned_buffer_page_end_16(src_uv);
free_aligned_buffer_page_end(dst_argb);
}
// Call P010ToAR30MatrixFilter() with a width that is not a multiple of 16.
// Verify there is no stack buffer overflow in P410ToAR30Row_Any_AVX2().
TEST_F(LibYUVConvertTest, P010ToAR30MatrixFilterOverflow) {
int width = 1024 + 15; // 1039
int height = 4;
int dst_stride_argb = width * 4;
align_buffer_page_end_16(src_y, width * height);
align_buffer_page_end_16(src_uv, width * ((height + 1) / 2));
align_buffer_page_end(dst_argb, dst_stride_argb * height);
memset(src_y, 0x02, width * height * sizeof(uint16_t));
memset(src_uv, 0x02, width * ((height + 1) / 2) * sizeof(uint16_t));
EXPECT_EQ(0, P010ToAR30MatrixFilter(src_y, width, src_uv, width, dst_argb,
dst_stride_argb, &kYuvI601Constants,
width, height, kFilterBilinear));
free_aligned_buffer_page_end_16(src_y);
free_aligned_buffer_page_end_16(src_uv);
free_aligned_buffer_page_end(dst_argb);
}
// Call P210ToAR30MatrixFilter(() with a width that is not a multiple of 16.
// Verify there is no stack buffer overflow in P410ToAR30Row_Any_AVX2().
TEST_F(LibYUVConvertTest, P210ToAR30MatrixFilterOverflow) {
int width = 1024 + 15; // 1039
int height = 4;
int dst_stride_ar30 = width * 4;
align_buffer_page_end_16(src_y, width * height);
align_buffer_page_end_16(src_uv, width * height);
align_buffer_page_end(dst_ar30, dst_stride_ar30 * height);
memset(src_y, 0x02, width * height * sizeof(uint16_t));
memset(src_uv, 0x02, width * height * sizeof(uint16_t));
EXPECT_EQ(0, P210ToAR30MatrixFilter(src_y, width, src_uv, width, dst_ar30,
dst_stride_ar30, &kYuvI601Constants,
width, height, kFilterBilinear));
free_aligned_buffer_page_end_16(src_y);
free_aligned_buffer_page_end_16(src_uv);
free_aligned_buffer_page_end(dst_ar30);
}
#ifdef ENABLE_ROW_TESTS
TEST_F(LibYUVConvertTest, TestARGBToUVMatrixRow_Opt) {
const int kMaxWidth = 128;