From 1e2e3a35993609da1d89ac170b907719d555f4b3 Mon Sep 17 00:00:00 2001 From: Wan-Teh Chang Date: Wed, 7 Oct 2026 15:02:36 -0700 Subject: [PATCH] Avoid integer overflow if src_height == +/-32768 The ScalePlaneBox(), ScalePlaneBox_16(), and ScaleUVBox() functions all contain the following expression: const int max_y = (src_height << 16); where src_height is a positive int. This expression overflows if src_height >= 32768. Tracing the callers, we make sure ScalePlane(), ScalePlane_16(), and UVScale() reject src_height < -32767 || src_height > 32767 as invalid input. (These functions negate a negative src_height before calling a function that executes expression src_height << 16.) Although UVScale_16() do not execute the expression src_height << 16, make the same change to UVScale_16() for consistency with UVScale(). Bug: chromium:531172025 Change-Id: Id5b10f11f46f593945cf6bf1435b6027a6629815 Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8524280 Reviewed-by: Frank Barchard Commit-Queue: Wan-Teh Chang --- source/scale.cc | 18 ++++++++++-------- source/scale_uv.cc | 6 +++--- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/source/scale.cc b/source/scale.cc index de815ab3d..ba06d42ea 100644 --- a/source/scale.cc +++ b/source/scale.cc @@ -2085,11 +2085,12 @@ int ScalePlane(const uint8_t* src, int dst_width, int dst_height, enum FilterMode filtering) { - // Reject dimensions larger than 32768 (or smaller than -32768 for height). - // This prevents FixedDiv signed integer overflows that can lead to division - // by zero/overflow crashes (SIGFPE on x86) or incorrect step calculations. + // Reject width larger than 32768 and height larger than 32767 or smaller than + // -32767. This prevents FixedDiv signed integer overflows that can lead to + // division by zero/overflow crashes (SIGFPE on x86) or incorrect step + // calculations. if (!src || src_width <= 0 || src_height == 0 || src_width > 32768 || - src_height < -32768 || src_height > 32768 || !dst || dst_width <= 0 || + src_height < -32767 || src_height > 32767 || !dst || dst_width <= 0 || dst_height <= 0) { return -1; } @@ -2200,11 +2201,12 @@ int ScalePlane_16(const uint16_t* src, int dst_width, int dst_height, enum FilterMode filtering) { - // Reject dimensions larger than 32768 (or smaller than -32768 for height). - // This prevents FixedDiv signed integer overflows that can lead to division - // by zero/overflow crashes (SIGFPE on x86) or incorrect step calculations. + // Reject width larger than 32768 and height larger than 32767 or smaller than + // -32767. This prevents FixedDiv signed integer overflows that can lead to + // division by zero/overflow crashes (SIGFPE on x86) or incorrect step + // calculations. if (!src || src_width <= 0 || src_height == 0 || src_width > 32768 || - src_height < -32768 || src_height > 32768 || !dst || dst_width <= 0 || + src_height < -32767 || src_height > 32767 || !dst || dst_width <= 0 || dst_height <= 0) { return -1; } diff --git a/source/scale_uv.cc b/source/scale_uv.cc index 78ec765c4..90dc8b2ce 100644 --- a/source/scale_uv.cc +++ b/source/scale_uv.cc @@ -1267,7 +1267,7 @@ int UVScale(const uint8_t* src_uv, int dst_height, enum FilterMode filtering) { if (!src_uv || src_width <= 0 || src_height == 0 || src_width > 32768 || - src_height < -32768 || src_height > 32768 || !dst_uv || dst_width <= 0 || + src_height < -32767 || src_height > 32767 || !dst_uv || dst_width <= 0 || dst_height <= 0) { return -1; } @@ -1290,8 +1290,8 @@ int UVScale_16(const uint16_t* src_uv, enum FilterMode filtering) { int dy = 0; - if (!src_uv || src_width <= 0 || src_height == 0 || src_height == INT_MIN || - src_width > 32768 || src_height > 32768 || !dst_uv || dst_width <= 0 || + if (!src_uv || src_width <= 0 || src_height == 0 || src_width > 32768 || + src_height < -32767 || src_height > 32767 || !dst_uv || dst_width <= 0 || dst_height <= 0) { return -1; }