From 3271bc9d5de94edc493c296ade8c50399f3b9e6b Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Wed, 22 Jul 2026 10:29:20 +0000 Subject: [PATCH] Check row allocations before pointer arithmetic Many conversion helpers allocated a temporary buffer with align_buffer_64() and then computed sub-row pointers from it before testing whether the allocation succeeded. align_buffer_64() yields a NULL base pointer on allocation failure, so these sub-row computations performed arithmetic on a NULL pointer (undefined behavior) before the `if (!row) return 1;` guard executed. Reorder the null check so it immediately follows each allocation, before any pointer arithmetic into the buffer, matching the correct convention already used elsewhere (e.g. convert_argb.cc:6465). Affected sites: convert_argb.cc: I444/I422/I420/I210/I010/P410 upsamplers (14 sites) convert.cc: two U/V row split allocations convert_from_argb.cc: four Y/U/V row split allocations planar_functions.cc: ARGBSobel row buffer split Cast-only sites that merely form (uint16_t*)row without arithmetic are well-defined on a NULL pointer and were intentionally left unchanged. R=fbarchard@google.com Change-Id: Id50912c9d10b021635ad72f0c920f324af1f5a8a --- source/convert.cc | 4 +-- source/convert_argb.cc | 56 ++++++++++++++++++------------------- source/convert_from_argb.cc | 12 ++++---- source/planar_functions.cc | 4 +-- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/source/convert.cc b/source/convert.cc index f341c7b85..1522bd685 100644 --- a/source/convert.cc +++ b/source/convert.cc @@ -777,9 +777,9 @@ int I010ToNV12(const uint16_t* src_y, { // Allocate a row of uv. align_buffer_64(row_u, ((halfwidth + 31) & ~31) * 2); - uint8_t* row_v = row_u + ((halfwidth + 31) & ~31); if (!row_u) return 1; + uint8_t* row_v = row_u + ((halfwidth + 31) & ~31); for (y = 0; y < halfheight; ++y) { Convert16To8Row(src_u, row_u, scale, halfwidth); @@ -1259,9 +1259,9 @@ int I422ToNV21(const uint8_t* src_y, // Allocate 2 rows of vu. int awidth = halfwidth * 2; align_buffer_64(row_vu_0, awidth * 2); - uint8_t* row_vu_1 = row_vu_0 + awidth; if (!row_vu_0) return 1; + uint8_t* row_vu_1 = row_vu_0 + awidth; for (y = 0; y < height - 1; y += 2) { MergeUVRow(src_v, src_u, row_vu_0, halfwidth); diff --git a/source/convert_argb.cc b/source/convert_argb.cc index 98c7effb9..431194987 100644 --- a/source/convert_argb.cc +++ b/source/convert_argb.cc @@ -6728,12 +6728,12 @@ static int I420ToARGBMatrixBilinear(const uint8_t* src_y, // alloc 4 lines temp const int row_size = (width + 31) & ~31; align_buffer_64(row, row_size * 4); + if (!row) + return 1; uint8_t* temp_u_1 = row; uint8_t* temp_u_2 = row + row_size; uint8_t* temp_v_1 = row + row_size * 2; uint8_t* temp_v_2 = row + row_size * 3; - if (!row) - return 1; ScaleRowUp2_Linear(src_u, temp_u_1, width); ScaleRowUp2_Linear(src_v, temp_v_1, width); @@ -6869,10 +6869,10 @@ static int I422ToARGBMatrixLinear(const uint8_t* src_y, // alloc 2 lines temp const int row_size = (width + 31) & ~31; align_buffer_64(row, row_size * 2); - uint8_t* temp_u = row; - uint8_t* temp_v = row + row_size; if (!row) return 1; + uint8_t* temp_u = row; + uint8_t* temp_v = row + row_size; for (y = 0; y < height; ++y) { ScaleRowUp2_Linear(src_u, temp_u, width); @@ -7005,12 +7005,12 @@ static int I420ToRGB24MatrixBilinear(const uint8_t* src_y, // alloc 4 lines temp const int row_size = (width + 31) & ~31; align_buffer_64(row, row_size * 4); + if (!row) + return 1; uint8_t* temp_u_1 = row; uint8_t* temp_u_2 = row + row_size; uint8_t* temp_v_1 = row + row_size * 2; uint8_t* temp_v_2 = row + row_size * 3; - if (!row) - return 1; ScaleRowUp2_Linear(src_u, temp_u_1, width); ScaleRowUp2_Linear(src_v, temp_v_1, width); @@ -7132,12 +7132,12 @@ static int I010ToAR30MatrixBilinear(const uint16_t* src_y, // alloc 4 lines temp const int row_size = (width + 31) & ~31; align_buffer_64(row, row_size * 4 * sizeof(uint16_t)); + if (!row) + return 1; uint16_t* temp_u_1 = (uint16_t*)(row); uint16_t* temp_u_2 = (uint16_t*)(row) + row_size; uint16_t* temp_v_1 = (uint16_t*)(row) + row_size * 2; uint16_t* temp_v_2 = (uint16_t*)(row) + row_size * 3; - if (!row) - return 1; ScaleRowUp2_Linear_12(src_u, temp_u_1, width); ScaleRowUp2_Linear_12(src_v, temp_v_1, width); @@ -7252,10 +7252,10 @@ static int I210ToAR30MatrixLinear(const uint16_t* src_y, // alloc 2 lines temp const int row_size = (width + 31) & ~31; align_buffer_64(row, row_size * 2 * sizeof(uint16_t)); - uint16_t* temp_u = (uint16_t*)(row); - uint16_t* temp_v = (uint16_t*)(row) + row_size; if (!row) return 1; + uint16_t* temp_u = (uint16_t*)(row); + uint16_t* temp_v = (uint16_t*)(row) + row_size; for (y = 0; y < height; ++y) { ScaleRowUp2_Linear_12(src_u, temp_u, width); @@ -7361,12 +7361,12 @@ static int I010ToARGBMatrixBilinear(const uint16_t* src_y, // alloc 4 lines temp const int row_size = (width + 31) & ~31; align_buffer_64(row, row_size * 4 * sizeof(uint16_t)); + if (!row) + return 1; uint16_t* temp_u_1 = (uint16_t*)(row); uint16_t* temp_u_2 = (uint16_t*)(row) + row_size; uint16_t* temp_v_1 = (uint16_t*)(row) + row_size * 2; uint16_t* temp_v_2 = (uint16_t*)(row) + row_size * 3; - if (!row) - return 1; ScaleRowUp2_Linear_12(src_u, temp_u_1, width); ScaleRowUp2_Linear_12(src_v, temp_v_1, width); @@ -7480,10 +7480,10 @@ static int I210ToARGBMatrixLinear(const uint16_t* src_y, // alloc 2 lines temp const int row_size = (width + 31) & ~31; align_buffer_64(row, row_size * 2 * sizeof(uint16_t)); - uint16_t* temp_u = (uint16_t*)(row); - uint16_t* temp_v = (uint16_t*)(row) + row_size; if (!row) return 1; + uint16_t* temp_u = (uint16_t*)(row); + uint16_t* temp_v = (uint16_t*)(row) + row_size; for (y = 0; y < height; ++y) { ScaleRowUp2_Linear_12(src_u, temp_u, width); @@ -7668,12 +7668,12 @@ static int I420AlphaToARGBMatrixBilinear( // alloc 4 lines temp const int row_size = (width + 31) & ~31; align_buffer_64(row, row_size * 4); + if (!row) + return 1; uint8_t* temp_u_1 = row; uint8_t* temp_u_2 = row + row_size; uint8_t* temp_v_1 = row + row_size * 2; uint8_t* temp_v_2 = row + row_size * 3; - if (!row) - return 1; ScaleRowUp2_Linear(src_u, temp_u_1, width); ScaleRowUp2_Linear(src_v, temp_v_1, width); @@ -7880,10 +7880,10 @@ static int I422AlphaToARGBMatrixLinear(const uint8_t* src_y, // alloc 2 lines temp const int row_size = (width + 31) & ~31; align_buffer_64(row, row_size * 2); - uint8_t* temp_u = row; - uint8_t* temp_v = row + row_size; if (!row) return 1; + uint8_t* temp_u = row; + uint8_t* temp_v = row + row_size; for (y = 0; y < height; ++y) { ScaleRowUp2_Linear(src_u, temp_u, width); @@ -8047,12 +8047,12 @@ static int I010AlphaToARGBMatrixBilinear( // alloc 4 lines temp const int row_size = (width + 31) & ~31; align_buffer_64(row, row_size * 4 * sizeof(uint16_t)); + if (!row) + return 1; uint16_t* temp_u_1 = (uint16_t*)(row); uint16_t* temp_u_2 = (uint16_t*)(row) + row_size; uint16_t* temp_v_1 = (uint16_t*)(row) + row_size * 2; uint16_t* temp_v_2 = (uint16_t*)(row) + row_size * 3; - if (!row) - return 1; ScaleRowUp2_Linear_12(src_u, temp_u_1, width); ScaleRowUp2_Linear_12(src_v, temp_v_1, width); @@ -8236,10 +8236,10 @@ static int I210AlphaToARGBMatrixLinear(const uint16_t* src_y, // alloc 2 lines temp const int row_size = (width + 31) & ~31; align_buffer_64(row, row_size * 2 * sizeof(uint16_t)); - uint16_t* temp_u = (uint16_t*)(row); - uint16_t* temp_v = (uint16_t*)(row) + row_size; if (!row) return 1; + uint16_t* temp_u = (uint16_t*)(row); + uint16_t* temp_v = (uint16_t*)(row) + row_size; for (y = 0; y < height; ++y) { ScaleRowUp2_Linear(src_u, temp_u, width); @@ -8342,10 +8342,10 @@ static int P010ToARGBMatrixBilinear(const uint16_t* src_y, // alloc 2 lines temp const int row_size = (2 * width + 31) & ~31; align_buffer_64(row, row_size * 2 * sizeof(uint16_t)); - uint16_t* temp_uv_1 = (uint16_t*)(row); - uint16_t* temp_uv_2 = (uint16_t*)(row) + row_size; if (!row) return 1; + uint16_t* temp_uv_1 = (uint16_t*)(row); + uint16_t* temp_uv_2 = (uint16_t*)(row) + row_size; Scale2RowUp_Bilinear_16(src_uv, 0, temp_uv_1, row_size, width); P410ToARGBRow(src_y, temp_uv_1, dst_argb, yuvconstants, width); @@ -8552,10 +8552,10 @@ static int P010ToAR30MatrixBilinear(const uint16_t* src_y, // alloc 2 lines temp const int row_size = (2 * width + 31) & ~31; align_buffer_64(row, row_size * 2 * sizeof(uint16_t)); - uint16_t* temp_uv_1 = (uint16_t*)(row); - uint16_t* temp_uv_2 = (uint16_t*)(row) + row_size; if (!row) return 1; + uint16_t* temp_uv_1 = (uint16_t*)(row); + uint16_t* temp_uv_2 = (uint16_t*)(row) + row_size; Scale2RowUp_Bilinear_16(src_uv, 0, temp_uv_1, row_size, width); P410ToAR30Row(src_y, temp_uv_1, dst_ar30, yuvconstants, width); @@ -8776,10 +8776,10 @@ static int I422ToRGB24MatrixLinear(const uint8_t* src_y, // alloc 2 lines temp const int row_size = (width + 31) & ~31; align_buffer_64(row, row_size * 2); - uint8_t* temp_u = row; - uint8_t* temp_v = row + row_size; if (!row) return 1; + uint8_t* temp_u = row; + uint8_t* temp_v = row + row_size; for (y = 0; y < height; ++y) { ScaleRowUp2_Linear(src_u, temp_u, width); diff --git a/source/convert_from_argb.cc b/source/convert_from_argb.cc index d5870a689..eea2c2890 100644 --- a/source/convert_from_argb.cc +++ b/source/convert_from_argb.cc @@ -555,9 +555,9 @@ int ARGBToNV12Matrix(const uint8_t* src_argb, // Allocate a rows of uv. align_buffer_64(row_u, ((halfwidth + 31) & ~31) * 2); - uint8_t* row_v = row_u + ((halfwidth + 31) & ~31); if (!row_u) return 1; + uint8_t* row_v = row_u + ((halfwidth + 31) & ~31); for (y = 0; y < height - 1; y += 2) { ARGBToUVMatrixRow(src_argb, src_stride_argb, row_u, row_v, width, @@ -770,9 +770,9 @@ int ARGBToNV21Matrix(const uint8_t* src_argb, // Allocate a rows of uv. align_buffer_64(row_u, ((halfwidth + 31) & ~31) * 2); - uint8_t* row_v = row_u + ((halfwidth + 31) & ~31); if (!row_u) return 1; + uint8_t* row_v = row_u + ((halfwidth + 31) & ~31); for (y = 0; y < height - 1; y += 2) { ARGBToUVMatrixRow(src_argb, src_stride_argb, row_u, row_v, width, @@ -948,10 +948,10 @@ int ARGBToYUY2Matrix(const uint8_t* src_argb, { align_buffer_64(row_y, ((width + 63) & ~63) * 2); - uint8_t* row_u = row_y + ((width + 63) & ~63); - uint8_t* row_v = row_u + ((width + 63) & ~63) / 2; if (!row_y) return 1; + uint8_t* row_u = row_y + ((width + 63) & ~63); + uint8_t* row_v = row_u + ((width + 63) & ~63) / 2; for (y = 0; y < height; ++y) { ARGBToUVMatrixRow(src_argb, 0, row_u, row_v, width, constants); @@ -1061,10 +1061,10 @@ int ARGBToUYVYMatrix(const uint8_t* src_argb, { align_buffer_64(row_y, ((width + 63) & ~63) * 2); - uint8_t* row_u = row_y + ((width + 63) & ~63); - uint8_t* row_v = row_u + ((width + 63) & ~63) / 2; if (!row_y) return 1; + uint8_t* row_u = row_y + ((width + 63) & ~63); + uint8_t* row_v = row_u + ((width + 63) & ~63) / 2; for (y = 0; y < height; ++y) { ARGBToUVMatrixRow(src_argb, 0, row_u, row_v, width, constants); diff --git a/source/planar_functions.cc b/source/planar_functions.cc index 3481d643d..2bef76d88 100644 --- a/source/planar_functions.cc +++ b/source/planar_functions.cc @@ -4957,6 +4957,8 @@ static int ARGBSobelize(const uint8_t* src_argb, // 3 rows with edges before/after. const int row_size = (width + kEdge + 31) & ~31; align_buffer_64(rows, row_size * 2 + (kEdge + row_size * 3 + kEdge)); + if (!rows) + return 1; uint8_t* row_sobelx = rows; uint8_t* row_sobely = rows + row_size; uint8_t* row_y = rows + row_size * 2; @@ -4965,8 +4967,6 @@ static int ARGBSobelize(const uint8_t* src_argb, uint8_t* row_y0 = row_y + kEdge; uint8_t* row_y1 = row_y0 + row_size; uint8_t* row_y2 = row_y1 + row_size; - if (!rows) - return 1; ARGBToYJRow(src_argb, row_y0, width); row_y0[-1] = row_y0[0]; memset(row_y0 + width, row_y0[width - 1], 16); // Extrude 16 for valgrind.