From 8561f45c2a36f6d3cdda41844c389b59445d0b22 Mon Sep 17 00:00:00 2001 From: Vincent Rabaud Date: Tue, 3 Sep 2024 14:16:22 +0200 Subject: [PATCH] Merge pull request #26084 from vrabaud:avif_check Avoid uninitialized value read in resize. #26084 When there is no point falling right, an hypothetical value is computed (but unused) using an uninitialized ofst. This triggers warnings in the sanitizers. Including those values in the for loops is also possible but messy when SIMD is involved. ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch --- modules/imgproc/src/resize.cpp | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/modules/imgproc/src/resize.cpp b/modules/imgproc/src/resize.cpp index 7e45f1e0f4..229b7f3ca5 100644 --- a/modules/imgproc/src/resize.cpp +++ b/modules/imgproc/src/resize.cpp @@ -95,6 +95,10 @@ static void hlineResize(ET* src, int cn, int *ofst, FT* m, FT* dst, int dst_min, } } } + // Avoid reading a potentially unset ofst, leading to a random memory read. + if (i >= dst_width) { + return; + } ET* src_last = src + cn*ofst[dst_width - 1]; for (; i < dst_width; i++) // Points that fall right from src image so became equal to rightmost src point { @@ -126,6 +130,10 @@ template struct hline ET* px = src + ofst[i]; *(dst++) = m[0] * px[0] + m[1] * px[1]; } + // Avoid reading a potentially unset ofst, leading to a random memory read. + if (i >= dst_width) { + return; + } src0 = (src + ofst[dst_width - 1])[0]; for (; i < dst_width; i++) // Points that fall right from src image so became equal to rightmost src point { @@ -150,6 +158,10 @@ template struct hline *(dst++) = m[0] * px[0] + m[1] * px[2]; *(dst++) = m[0] * px[1] + m[1] * px[3]; } + // Avoid reading a potentially unset ofst, leading to a random memory read. + if (i >= dst_width) { + return; + } src0 = (src + 2*ofst[dst_width - 1])[0]; src1 = (src + 2*ofst[dst_width - 1])[1]; for (; i < dst_width; i++) // Points that fall right from src image so became equal to rightmost src point @@ -178,6 +190,10 @@ template struct hline *(dst++) = m[0] * px[1] + m[1] * px[4]; *(dst++) = m[0] * px[2] + m[1] * px[5]; } + // Avoid reading a potentially unset ofst, leading to a random memory read. + if (i >= dst_width) { + return; + } src0 = (src + 3*ofst[dst_width - 1])[0]; src1 = (src + 3*ofst[dst_width - 1])[1]; src2 = (src + 3*ofst[dst_width - 1])[2]; @@ -210,6 +226,10 @@ template struct hline *(dst++) = m[0] * px[2] + m[1] * px[6]; *(dst++) = m[0] * px[3] + m[1] * px[7]; } + // Avoid reading a potentially unset ofst, leading to a random memory read. + if (i >= dst_width) { + return; + } src0 = (src + 4*ofst[dst_width - 1])[0]; src1 = (src + 4*ofst[dst_width - 1])[1]; src2 = (src + 4*ofst[dst_width - 1])[2]; @@ -238,6 +258,10 @@ template struct hline ET* px = src + ofst[i]; *(dst++) = m[0] * src[0] + m[1] * src[1] + m[2] * src[2] + m[3] * src[3]; } + // Avoid reading a potentially unset ofst, leading to a random memory read. + if (i >= dst_width) { + return; + } src0 = (src + ofst[dst_width - 1])[0]; for (; i < dst_width; i++) // Points that fall right from src image so became equal to rightmost src point { @@ -262,6 +286,10 @@ template struct hline *(dst++) = m[0] * src[0] + m[1] * src[2] + m[2] * src[4] + m[3] * src[6]; *(dst++) = m[0] * src[1] + m[1] * src[3] + m[2] * src[5] + m[3] * src[7]; } + // Avoid reading a potentially unset ofst, leading to a random memory read. + if (i >= dst_width) { + return; + } src0 = (src + 2*ofst[dst_width - 1])[0]; src1 = (src + 2*ofst[dst_width - 1])[1]; for (; i < dst_width; i++) // Points that fall right from src image so became equal to rightmost src point @@ -290,6 +318,10 @@ template struct hline *(dst++) = m[0] * src[1] + m[1] * src[4] + m[2] * src[7] + m[3] * src[10]; *(dst++) = m[0] * src[2] + m[1] * src[5] + m[2] * src[8] + m[3] * src[11]; } + // Avoid reading a potentially unset ofst, leading to a random memory read. + if (i >= dst_width) { + return; + } src0 = (src + 3*ofst[dst_width - 1])[0]; src1 = (src + 3*ofst[dst_width - 1])[1]; src2 = (src + 3*ofst[dst_width - 1])[2]; @@ -322,6 +354,10 @@ template struct hline *(dst++) = m[0] * src[2] + m[1] * src[6] + m[2] * src[10] + m[3] * src[14]; *(dst++) = m[0] * src[3] + m[1] * src[7] + m[2] * src[11] + m[3] * src[15]; } + // Avoid reading a potentially unset ofst, leading to a random memory read. + if (i >= dst_width) { + return; + } src0 = (src + 4*ofst[dst_width - 1])[0]; src1 = (src + 4*ofst[dst_width - 1])[1]; src2 = (src + 4*ofst[dst_width - 1])[2]; @@ -383,6 +419,10 @@ void hlineResizeCn(uint8_t* src, int, int *o uint8_t* px = src + ofst[i]; *(dst++) = m[0] * px[0] + m[1] * px[1]; } + // Avoid reading a potentially unset ofst, leading to a random memory read. + if (i >= dst_width) { + return; + } src_0 = (src + ofst[dst_width - 1])[0]; #if (CV_SIMD || CV_SIMD_SCALABLE) v_src_0 = vx_setall_u16(*((uint16_t*)&src_0)); @@ -439,6 +479,10 @@ void hlineResizeCn(uint8_t* src, int, int *o *(dst++) = m[0] * px[0] + m[1] * px[2]; *(dst++) = m[0] * px[1] + m[1] * px[3]; } + // Avoid reading a potentially unset ofst, leading to a random memory read. + if (i >= dst_width) { + return; + } ((ufixedpoint16*)(srccn.w))[0] = (src + 2 * ofst[dst_width - 1])[0]; ((ufixedpoint16*)(srccn.w))[1] = (src + 2 * ofst[dst_width - 1])[1]; #if (CV_SIMD || CV_SIMD_SCALABLE) v_srccn = v_reinterpret_as_u16(vx_setall_u32(srccn.d)); @@ -511,6 +555,10 @@ void hlineResizeCn(uint8_t* src, int, int *o *(dst++) = m[0] * px[1] + m[1] * px[4]; *(dst++) = m[0] * px[2] + m[1] * px[5]; } + // Avoid reading a potentially unset ofst, leading to a random memory read. + if (i >= dst_width) { + return; + } ((ufixedpoint16*)(srccn.w))[0] = (src + 3*ofst[dst_width - 1])[0]; ((ufixedpoint16*)(srccn.w))[1] = (src + 3*ofst[dst_width - 1])[1]; ((ufixedpoint16*)(srccn.w))[2] = (src + 3*ofst[dst_width - 1])[2]; @@ -584,6 +632,10 @@ void hlineResizeCn(uint8_t* src, int, int *o *(dst++) = m[0] * px[2] + m[1] * px[6]; *(dst++) = m[0] * px[3] + m[1] * px[7]; } + // Avoid reading a potentially unset ofst, leading to a random memory read. + if (i >= dst_width) { + return; + } ((ufixedpoint16*)(srccn.w))[0] = (src + 4 * ofst[dst_width - 1])[0]; ((ufixedpoint16*)(srccn.w))[1] = (src + 4 * ofst[dst_width - 1])[1]; ((ufixedpoint16*)(srccn.w))[2] = (src + 4 * ofst[dst_width - 1])[2]; ((ufixedpoint16*)(srccn.w))[3] = (src + 4 * ofst[dst_width - 1])[3]; #if (CV_SIMD || CV_SIMD_SCALABLE) @@ -635,6 +687,10 @@ void hlineResizeCn(uint16_t* src, int, int uint16_t* px = src + ofst[i]; *(dst++) = m[0] * px[0] + m[1] * px[1]; } + // Avoid reading a potentially unset ofst, leading to a random memory read. + if (i >= dst_width) { + return; + } src_0 = (src + ofst[dst_width - 1])[0]; #if (CV_SIMD || CV_SIMD_SCALABLE) v_src_0 = vx_setall_u32(*((uint32_t*)&src_0));