PR #25468 opened by Kilian (lusoris) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25468 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25468.patch
This patch addresses GCC 14.4.0 and 16.2.1 -Wstringop-overflow diagnostics in angular prediction in libavcodec/rv60dec.c. What the patch does: - `avcodec/rv60dec: validate angular prediction buffer bounds`: requires power-of-two block sizes from 4 to 64 and bounds weak and bilinear filter lengths, returning invalid data for unsupported sizes or out-of-range lengths. Behaviour change: invalid sizes and filter lengths return an error; prediction within the supported bounds is unchanged. Base: FFmpeg master 46f23be8b1. Testing: - GCC 14.4.0 (`--enable-gpl --enable-vulkan`) and GCC 16.2.1 (`--enable-gpl --enable-vulkan --enable-vaapi --enable-libdrm --enable-nvenc`), targets all, alltools, examples, testprogs and checkasm: master 46f23be8b1 shows 10 -Wstringop-overflow warnings in libavcodec/rv60dec.c with each compiler; with this patch there are none and no new ones. - `make fate-rv60` (2 tests) passes on master and with this patch. Split out of #25111 so that each part reaches the reviewers for its area. pross reviewed this change in #25111. >From aa01da3053321a8ffdf67926f5d71eb059b5b2ba Mon Sep 17 00:00:00 2001 From: lusoris <[email protected]> Date: Thu, 15 Oct 2026 22:06:35 +0200 Subject: [PATCH] avcodec/rv60dec: validate angular prediction buffer bounds GCC 14.4.0 and 16.2.1 report -Wstringop-overflow in angular prediction. Unchecked block sizes and derived filter lengths could exceed the local reference buffer. Require a power-of-two size from 4 to 64 and bound the weak and bilinear filter lengths before writing. Prediction is unchanged for sizes and lengths within those bounds. Signed-off-by: lusoris <[email protected]> --- libavcodec/rv60dec.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/libavcodec/rv60dec.c b/libavcodec/rv60dec.c index 2a7c5c11470..555e1b8081c 100644 --- a/libavcodec/rv60dec.c +++ b/libavcodec/rv60dec.c @@ -662,6 +662,9 @@ static int pred_angle(const IntraPredContext * p, uint8_t * dst, int stride, int { uint8_t filtered1[96], filtered2[96]; + if (size < 4 || size > 64 || (size & (size - 1))) + return AVERROR_INVALIDDATA; + if (!imode) { pred_plane(p, dst, stride, size); } else if (imode == 1) { @@ -670,8 +673,13 @@ static int pred_angle(const IntraPredContext * p, uint8_t * dst, int stride, int int ang_weight = rv60_ipred_angle[10 - imode]; int add_size = (size * ang_weight + 31) >> 5; if (size <= 16) { - filter_weak(filtered1 + 32, &p->l[1], size + add_size); + const int filtered_size = size + add_size; + if (filtered_size < 1 || filtered_size > 64) + return AVERROR_INVALIDDATA; + filter_weak(filtered1 + 32, &p->l[1], filtered_size); } else { + if (add_size < 0 || add_size > 32) + return AVERROR_INVALIDDATA; filter_bilin32(filtered1 + 32, p->l[1], p->l[33], 32); filter_bilin32(filtered1 + 64, p->l[32], p->l[64], add_size); } @@ -746,9 +754,14 @@ static int pred_angle(const IntraPredContext * p, uint8_t * dst, int stride, int } else if (imode <= 34) { int ang_weight = rv60_ipred_angle[imode - 26]; int add_size = (size * ang_weight + 31) >> 5; - if (size <= 16) - filter_weak(&filtered1[32], &p->t[1], size + add_size); - else { + if (size <= 16) { + const int filtered_size = size + add_size; + if (filtered_size < 1 || filtered_size > 64) + return AVERROR_INVALIDDATA; + filter_weak(&filtered1[32], &p->t[1], filtered_size); + } else { + if (add_size < 0 || add_size > 32) + return AVERROR_INVALIDDATA; filter_bilin32(filtered1 + 32, p->t[1], p->t[33], 32); filter_bilin32(filtered1 + 64, p->t[32], p->t[64], add_size); } -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
