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
This commit is contained in:
Vincent Rabaud 2024-09-03 14:16:22 +02:00 committed by GitHub
parent 88f99edc65
commit 8561f45c2a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -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 <typename ET, typename FT> struct hline<ET, FT, 2, true, 1>
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 <typename ET, typename FT> struct hline<ET, FT, 2, true, 2>
*(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 <typename ET, typename FT> struct hline<ET, FT, 2, true, 3>
*(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 <typename ET, typename FT> struct hline<ET, FT, 2, true, 4>
*(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 <typename ET, typename FT> struct hline<ET, FT, 4, true, 1>
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 <typename ET, typename FT> struct hline<ET, FT, 4, true, 2>
*(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 <typename ET, typename FT> struct hline<ET, FT, 4, true, 3>
*(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 <typename ET, typename FT> struct hline<ET, FT, 4, true, 4>
*(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, ufixedpoint16, 2, true, 1>(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, ufixedpoint16, 2, true, 2>(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, ufixedpoint16, 2, true, 3>(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, ufixedpoint16, 2, true, 4>(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, ufixedpoint32, 2, true, 1>(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));