PR #25120 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25120 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25120.patch
>From 14380e060aaf3d45b0ea638c19d6d4d84cc71a33 Mon Sep 17 00:00:00 2001 From: zhang xingxing <[email protected]> Date: Thu, 15 Oct 2026 03:53:08 +0200 Subject: [PATCH 01/12] avfilter/vf_avgblur: compute max * area in 64bit Fixes: out of array read Fixes: BxsBdfl8050I Fixes: swarm-Signed-integer-overflow-in-build_lut-slow-check-enables-heap-OOB-read-ba3309 Regression since: a7fc78c1a6 Out of array read Replicated through UnModified FFmpeg with ASAN Found-by: zhang xingxing <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> --- libavfilter/vf_avgblur.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_avgblur.c b/libavfilter/vf_avgblur.c index 3bd4faa5f6..66c046471e 100644 --- a/libavfilter/vf_avgblur.c +++ b/libavfilter/vf_avgblur.c @@ -174,7 +174,7 @@ static void build_lut(AVFilterContext *ctx, int max) const int area = (2 * s->radiusV + 1) * (2 * s->radius + 1); s->area = area; - if (max * area >= FF_ARRAY_ELEMS(s->lut)) + if ((int64_t)max * area >= FF_ARRAY_ELEMS(s->lut)) return; for (int i = 0, j = 0, k = 0; i < max * area; i++, j++) { @@ -234,7 +234,7 @@ static void averageiir2d(AVFilterContext *ctx, AVFrame *in, AVFrame *out, int pl AverageBlurContext *s = ctx->priv; const int width = s->planewidth[plane]; const int height = s->planeheight[plane]; - const int slow = (s->max * s->area) >= FF_ARRAY_ELEMS(s->lut); + const int slow = ((int64_t)s->max * s->area) >= FF_ARRAY_ELEMS(s->lut); ThreadData td; td.width = width; -- 2.54.0 >From 363b94a55972cf50192603b72a19f5793500a142 Mon Sep 17 00:00:00 2001 From: zhang xingxing <[email protected]> Date: Thu, 15 Oct 2026 04:01:57 +0200 Subject: [PATCH 02/12] avformat/idroqdec: skip the whole body of a repeated RoQ_INFO chunk The RoQ player in the Quake III Arena source (code/client/cl_cin.c) also continues after the declared size of every RoQ_INFO chunk. Fixes: yyLBi9GsHV9w Fixes: swarm-RoQ_INFO-re-entry-skips-fixed-size-ignoring-chunk_size-e7709a Stream desynchronization Replicated through UnModified FFmpeg Found-by: zhang xingxing <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> --- libavformat/idroqdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/idroqdec.c b/libavformat/idroqdec.c index 861338ceec..76d96196ba 100644 --- a/libavformat/idroqdec.c +++ b/libavformat/idroqdec.c @@ -142,7 +142,7 @@ static int roq_read_packet(AVFormatContext *s, break; } /* don't care about this chunk anymore */ - avio_skip(pb, RoQ_CHUNK_PREAMBLE_SIZE); + avio_skip(pb, chunk_size); break; case RoQ_QUAD_CODEBOOK: -- 2.54.0 >From 98eae281668d6260753ef1e30b822361b9068871 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Thu, 15 Oct 2026 04:03:02 +0200 Subject: [PATCH 03/12] avformat/idroqdec: compute the codebook and VQ packet size in 64bit Fixes: yyLBi9GsHV9w Packet size wraparound Replicated through UnModified FFmpeg Found-by: zhang xingxing <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> --- libavformat/idroqdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/idroqdec.c b/libavformat/idroqdec.c index 76d96196ba..ad904b42b4 100644 --- a/libavformat/idroqdec.c +++ b/libavformat/idroqdec.c @@ -99,7 +99,7 @@ static int roq_read_packet(AVFormatContext *s, RoqDemuxContext *roq = s->priv_data; AVIOContext *pb = s->pb; int ret = 0; - unsigned int chunk_size; + int64_t chunk_size; unsigned int chunk_type; unsigned int codebook_size; unsigned char preamble[RoQ_CHUNK_PREAMBLE_SIZE]; @@ -154,7 +154,7 @@ static int roq_read_packet(AVFormatContext *s, avio_skip(pb, codebook_size); if ((ret = ffio_read_size(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE)) < 0) return ret; - chunk_size = AV_RL32(&preamble[2]) + RoQ_CHUNK_PREAMBLE_SIZE * 2 + + chunk_size = (int64_t)AV_RL32(&preamble[2]) + RoQ_CHUNK_PREAMBLE_SIZE * 2 + codebook_size; if (chunk_size > INT_MAX) -- 2.54.0 >From 26fb03a862178952884c6003271cf6d0f07b121d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Thu, 15 Oct 2026 04:06:26 +0200 Subject: [PATCH 04/12] avfilter/vf_pad: do the x/y range check and centering in 64bit Fixes: Ilayk1MzOixN Fixes: swarm-Signed-integer-overflow-in-pad-x-y-bounds-check-499261 Regression since: 57c3670896 Signed integer overflow Replicated through UnModified FFmpeg with UBSAN Found-by: zhang xingxing <[email protected]> The report suggested, among other options, widening the comparison. The overflow in the centering was found during review of the fixes for the report. Signed-off-by: Michael Niedermayer <[email protected]> --- libavfilter/vf_pad.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c index a3436bb2d6..4891cf2518 100644 --- a/libavfilter/vf_pad.c +++ b/libavfilter/vf_pad.c @@ -180,10 +180,10 @@ static int config_input(AVFilterLink *inlink) goto eval_fail; s->x = var_values[VAR_X] = res; - if (s->x < 0 || s->x + inlink->w > s->w) - s->x = var_values[VAR_X] = (s->w - inlink->w) / 2; - if (s->y < 0 || s->y + inlink->h > s->h) - s->y = var_values[VAR_Y] = (s->h - inlink->h) / 2; + if (s->x < 0 || (int64_t)s->x + inlink->w > s->w) + s->x = var_values[VAR_X] = ((int64_t)s->w - inlink->w) / 2; + if (s->y < 0 || (int64_t)s->y + inlink->h > s->h) + s->y = var_values[VAR_Y] = ((int64_t)s->h - inlink->h) / 2; s->w = ff_draw_round_to_sub(&s->draw, 0, -1, s->w); s->h = ff_draw_round_to_sub(&s->draw, 1, -1, s->h); -- 2.54.0 >From df628b13030b58aa3e48b7d260366e4fb14a8dc9 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Thu, 15 Oct 2026 04:06:26 +0200 Subject: [PATCH 05/12] avfilter/vf_pad_vaapi: do the x/y range check and centering in 64bit Fixes: Ilayk1MzOixN Fixes: swarm-Signed-integer-overflow-in-pad-x-y-bounds-check-499261 Regression since: 42eb10ecc6 Found-by: zhang xingxing <[email protected]> The report suggested, among other options, widening the comparison. The overflow in the centering was found during review of the fixes for the report. Signed-off-by: Michael Niedermayer <[email protected]> --- libavfilter/vf_pad_vaapi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavfilter/vf_pad_vaapi.c b/libavfilter/vf_pad_vaapi.c index 5e9dad3065..a6ceae5b75 100644 --- a/libavfilter/vf_pad_vaapi.c +++ b/libavfilter/vf_pad_vaapi.c @@ -133,10 +133,10 @@ static int pad_vaapi_config_output(AVFilterLink *outlink) return ret; ctx->x = var_values[VAR_X] = res; - if (ctx->x < 0 || ctx->x + inlink->w > ctx->w) - ctx->x = var_values[VAR_X] = (ctx->w - inlink->w) / 2; - if (ctx->y < 0 || ctx->y + inlink->h > ctx->h) - ctx->y = var_values[VAR_Y] = (ctx->h - inlink->h) / 2; + if (ctx->x < 0 || (int64_t)ctx->x + inlink->w > ctx->w) + ctx->x = var_values[VAR_X] = ((int64_t)ctx->w - inlink->w) / 2; + if (ctx->y < 0 || (int64_t)ctx->y + inlink->h > ctx->h) + ctx->y = var_values[VAR_Y] = ((int64_t)ctx->h - inlink->h) / 2; /* sanity check params */ if (ctx->w < inlink->w || ctx->h < inlink->h) { -- 2.54.0 >From 850fc52acccf052ac259135dac16331c4fbf751e Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Thu, 15 Oct 2026 04:34:32 +0200 Subject: [PATCH 06/12] avformat/sctp: return AVERROR_EOF when the peer closes the association Fixes: WoBBcuySgSTx Fixes: swarm-sctp_read-returns-2-on-graceful-close-never-signalling-EOF-2a7ba0 Endless loop Replicated through UnModified FFmpeg Found-by: zhang xingxing <[email protected]> The report suggested not adding the stream id size when recvmsg() returns 0. The case without max_streams was found during triage of the report. Signed-off-by: Michael Niedermayer <[email protected]> --- libavformat/sctp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavformat/sctp.c b/libavformat/sctp.c index 0efac12d96..ed132f1851 100644 --- a/libavformat/sctp.c +++ b/libavformat/sctp.c @@ -309,17 +309,19 @@ static int sctp_read(URLContext *h, uint8_t *buf, int size) } if (s->max_streams) { - if (size < 2) + if (size <= 2) return AVERROR(EINVAL); /*StreamId is introduced as a 2byte code into the stream*/ struct sctp_sndrcvinfo info = { 0 }; ret = ff_sctp_recvmsg(s->fd, buf + 2, size - 2, NULL, 0, &info, 0); AV_WB16(buf, info.sinfo_stream); - ret = ret < 0 ? ret : ret + 2; + ret = ret <= 0 ? ret : ret + 2; } else ret = recv(s->fd, buf, size, 0); + if (!ret) + return AVERROR_EOF; return ret < 0 ? ff_neterrno() : ret; } -- 2.54.0 >From 925c50e4f2ff108fe8580ef1c3b6dc6f08c48f5a Mon Sep 17 00:00:00 2001 From: zhang xingxing <[email protected]> Date: Thu, 15 Oct 2026 04:35:44 +0200 Subject: [PATCH 07/12] avcodec/tiff_common: do not size the metadata bprint from count Fixes: 0gCI9NJKm3tO Fixes: swarm-Signed-overflow-of-10-count-100-count-in-av_bprint_init-f6bdbe Regression since: b7ba7cbd6e Signed integer overflow Replicated through UnModified FFmpeg with UBSAN Found-by: zhang xingxing <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> --- libavcodec/tiff_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/tiff_common.c b/libavcodec/tiff_common.c index 265f843031..c4c672632a 100644 --- a/libavcodec/tiff_common.c +++ b/libavcodec/tiff_common.c @@ -108,7 +108,7 @@ int ff_tadd_doubles_metadata(int count, const char *name, const char *sep, if (bytestream2_get_bytes_left(gb) < count * sizeof(int64_t)) return AVERROR_INVALIDDATA; - av_bprint_init(&bp, 10 * count, 100 * count); + av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED); for (i = 0; i < count; i++) { av_bprintf(&bp, "%s%.15g", auto_sep(count, sep, i, 4), ff_tget_double(gb, le)); @@ -129,7 +129,7 @@ int ff_tadd_shorts_metadata(int count, const char *name, const char *sep, if (bytestream2_get_bytes_left(gb) < count * sizeof(int16_t)) return AVERROR_INVALIDDATA; - av_bprint_init(&bp, 10 * count, AV_BPRINT_SIZE_UNLIMITED); + av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED); for (i = 0; i < count; i++) { int v = is_signed ? (int16_t)ff_tget_short(gb, le) : ff_tget_short(gb, le); -- 2.54.0 >From 253ece0df43583e8502ab912a7dcf52021dfb357 Mon Sep 17 00:00:00 2001 From: zhang xingxing <[email protected]> Date: Thu, 15 Oct 2026 04:46:24 +0200 Subject: [PATCH 08/12] avfilter/vf_stack: use ff_slice_pos() for the per-slice input range Fixes: GIRN0tvt58WQ Fixes: swarm-Signed-integer-overflow-in-process_slice-slice-computation-b29bec Regression since: 631f7acc6c Out of array read Replicated through UnModified FFmpeg with ASAN Found-by: zhang xingxing <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> --- libavfilter/vf_stack.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c index 6e9ac60a56..19c4b2c147 100644 --- a/libavfilter/vf_stack.c +++ b/libavfilter/vf_stack.c @@ -148,8 +148,8 @@ static int process_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) StackContext *s = ctx->priv; AVFrame *out = arg; AVFrame **in = s->frames; - const int start = (s->nb_inputs * job ) / nb_jobs; - const int end = (s->nb_inputs * (job+1)) / nb_jobs; + const int start = ff_slice_pos(s->nb_inputs, job, nb_jobs); + const int end = ff_slice_pos(s->nb_inputs, job + 1, nb_jobs); for (int i = start; i < end; i++) { StackItem *item = &s->items[i]; -- 2.54.0 >From 830c67c8de1d0acd8549eea0f17ee55c2fdc9424 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Thu, 15 Oct 2026 04:46:24 +0200 Subject: [PATCH 09/12] avfilter: use ff_slice_pos() in the remaining slice threaded filters This is a behavior preserving change for all non-overflowing cases. Found during triage of the security report GIRN0tvt58WQ Signed-off-by: Michael Niedermayer <[email protected]> --- libavfilter/vf_framerate.c | 4 ++-- libavfilter/vf_hflip.c | 4 ++-- libavfilter/vf_lenscorrection.c | 8 ++++---- libavfilter/vf_perspective.c | 8 ++++---- libavfilter/vf_readeia608.c | 4 ++-- libavfilter/vf_rotate.c | 4 ++-- libavfilter/vsrc_gradients.c | 12 ++++++------ libavfilter/vsrc_sierpinski.c | 8 ++++---- libavfilter/vsrc_testsrc.c | 4 ++-- 9 files changed, 28 insertions(+), 28 deletions(-) diff --git a/libavfilter/vf_framerate.c b/libavfilter/vf_framerate.c index 468042e7db..d603483c29 100644 --- a/libavfilter/vf_framerate.c +++ b/libavfilter/vf_framerate.c @@ -101,8 +101,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) int plane; for (plane = 0; plane < 4 && src1->data[plane] && src2->data[plane]; plane++) { - const int start = (s->height[plane] * job ) / nb_jobs; - const int end = (s->height[plane] * (job+1)) / nb_jobs; + const int start = ff_slice_pos(s->height[plane], job, nb_jobs); + const int end = ff_slice_pos(s->height[plane], job + 1, nb_jobs); uint8_t *src1_data = src1->data[plane] + start * src1->linesize[plane]; uint8_t *src2_data = src2->data[plane] + start * src2->linesize[plane]; uint8_t *dst_data = work->data[plane] + start * work->linesize[plane]; diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c index 8f8dd14240..2c1c2c4120 100644 --- a/libavfilter/vf_hflip.c +++ b/libavfilter/vf_hflip.c @@ -93,8 +93,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) { const int width = s->planewidth[plane] / s->bayer_plus1; const int height = s->planeheight[plane]; - const int start = (height * job ) / nb_jobs; - const int end = (height * (job+1)) / nb_jobs; + const int start = ff_slice_pos(height, job, nb_jobs); + const int end = ff_slice_pos(height, job + 1, nb_jobs); step = s->max_step[plane]; diff --git a/libavfilter/vf_lenscorrection.c b/libavfilter/vf_lenscorrection.c index 15c2e99e4b..945e456c41 100644 --- a/libavfilter/vf_lenscorrection.c +++ b/libavfilter/vf_lenscorrection.c @@ -86,8 +86,8 @@ static int filter##name##_slice(AVFilterContext *ctx, void *arg, int job, \ const int w = rect->planewidth[plane], h = rect->planeheight[plane]; \ const int xcenter = rect->cx * w; \ const int ycenter = rect->cy * h; \ - const int start = (h * job ) / nb_jobs; \ - const int end = (h * (job+1)) / nb_jobs; \ + const int start = ff_slice_pos(h, job, nb_jobs); \ + const int end = ff_slice_pos(h, job + 1, nb_jobs); \ const int inlinesize = in->linesize[plane] / sizeof(type); \ const int outlinesize = out->linesize[plane] / sizeof(type); \ const type *indata = (const type *)in->data[plane]; \ @@ -128,8 +128,8 @@ static int filter##name##_slice_bilinear(AVFilterContext *ctx, void *arg, \ const int w = rect->planewidth[plane], h = rect->planeheight[plane]; \ const int xcenter = rect->cx * w; \ const int ycenter = rect->cy * h; \ - const int start = (h * job ) / nb_jobs; \ - const int end = (h * (job+1)) / nb_jobs; \ + const int start = ff_slice_pos(h, job, nb_jobs); \ + const int end = ff_slice_pos(h, job + 1, nb_jobs); \ const int inlinesize = in->linesize[plane] / sizeof(type); \ const int outlinesize = out->linesize[plane] / sizeof(type); \ const type *indata = (const type *)in->data[plane]; \ diff --git a/libavfilter/vf_perspective.c b/libavfilter/vf_perspective.c index 58510f6f13..184de78d36 100644 --- a/libavfilter/vf_perspective.c +++ b/libavfilter/vf_perspective.c @@ -286,8 +286,8 @@ static int resample_cubic(AVFilterContext *ctx, void *arg, int h = td->h; int hsub = td->hsub; int vsub = td->vsub; - int start = (h * job) / nb_jobs; - int end = (h * (job+1)) / nb_jobs; + int start = ff_slice_pos(h, job, nb_jobs); + int end = ff_slice_pos(h, job + 1, nb_jobs); const int linesize = s->linesize[0]; int x, y; @@ -365,8 +365,8 @@ static int resample_linear(AVFilterContext *ctx, void *arg, int h = td->h; int hsub = td->hsub; int vsub = td->vsub; - int start = (h * job) / nb_jobs; - int end = (h * (job+1)) / nb_jobs; + int start = ff_slice_pos(h, job, nb_jobs); + int end = ff_slice_pos(h, job + 1, nb_jobs); const int linesize = s->linesize[0]; int x, y; diff --git a/libavfilter/vf_readeia608.c b/libavfilter/vf_readeia608.c index 605ca86d17..86e9019356 100644 --- a/libavfilter/vf_readeia608.c +++ b/libavfilter/vf_readeia608.c @@ -446,8 +446,8 @@ static int extract_lines(AVFilterContext *ctx, void *arg, ReadEIA608Context *s = ctx->priv; AVFilterLink *inlink = ctx->inputs[0]; const int h = s->end - s->start + 1; - const int start = (h * job) / nb_jobs; - const int end = (h * (job+1)) / nb_jobs; + const int start = ff_slice_pos(h, job, nb_jobs); + const int end = ff_slice_pos(h, job + 1, nb_jobs); AVFrame *in = arg; for (int i = start; i < end; i++) { diff --git a/libavfilter/vf_rotate.c b/libavfilter/vf_rotate.c index 740acfe3bd..4640f175bb 100644 --- a/libavfilter/vf_rotate.c +++ b/libavfilter/vf_rotate.c @@ -420,8 +420,8 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) const int plane = td->plane; const int xi = td->xi, yi = td->yi; const int c = td->c, s = td->s; - const int start = (outh * job ) / nb_jobs; - const int end = (outh * (job+1)) / nb_jobs; + const int start = ff_slice_pos(outh, job, nb_jobs); + const int end = ff_slice_pos(outh, job + 1, nb_jobs); int xprime = td->xprime + start * s; int yprime = td->yprime + start * c; int i, j, x, y; diff --git a/libavfilter/vsrc_gradients.c b/libavfilter/vsrc_gradients.c index cb1b73773f..d6294d3309 100644 --- a/libavfilter/vsrc_gradients.c +++ b/libavfilter/vsrc_gradients.c @@ -254,8 +254,8 @@ static int draw_gradients_slice(AVFilterContext *ctx, void *arg, int job, int nb AVFrame *frame = arg; const int width = frame->width; const int height = frame->height; - const int start = (height * job ) / nb_jobs; - const int end = (height * (job+1)) / nb_jobs; + const int start = ff_slice_pos(height, job, nb_jobs); + const int end = ff_slice_pos(height, job + 1, nb_jobs); const ptrdiff_t linesize = frame->linesize[0] / 4; uint32_t *dst = (uint32_t *)frame->data[0] + start * linesize; const int type = s->type; @@ -278,8 +278,8 @@ static int draw_gradients_slice16(AVFilterContext *ctx, void *arg, int job, int AVFrame *frame = arg; const int width = frame->width; const int height = frame->height; - const int start = (height * job ) / nb_jobs; - const int end = (height * (job+1)) / nb_jobs; + const int start = ff_slice_pos(height, job, nb_jobs); + const int end = ff_slice_pos(height, job + 1, nb_jobs); const ptrdiff_t linesize = frame->linesize[0] / 8; uint64_t *dst = (uint64_t *)frame->data[0] + start * linesize; const int type = s->type; @@ -302,8 +302,8 @@ static int draw_gradients_slice32_planar(AVFilterContext *ctx, void *arg, int jo AVFrame *frame = arg; const int width = frame->width; const int height = frame->height; - const int start = (height * job ) / nb_jobs; - const int end = (height * (job+1)) / nb_jobs; + const int start = ff_slice_pos(height, job, nb_jobs); + const int end = ff_slice_pos(height, job + 1, nb_jobs); const ptrdiff_t linesize_g = frame->linesize[0] / 4; const ptrdiff_t linesize_b = frame->linesize[1] / 4; const ptrdiff_t linesize_r = frame->linesize[2] / 4; diff --git a/libavfilter/vsrc_sierpinski.c b/libavfilter/vsrc_sierpinski.c index c9134184a5..77a0c6cdc2 100644 --- a/libavfilter/vsrc_sierpinski.c +++ b/libavfilter/vsrc_sierpinski.c @@ -91,8 +91,8 @@ static int draw_triangle_slice(AVFilterContext *ctx, void *arg, int job, int nb_ AVFrame *frame = arg; const int width = frame->width; const int height = frame->height; - const int start = (height * job ) / nb_jobs; - const int end = (height * (job+1)) / nb_jobs; + const int start = ff_slice_pos(height, job, nb_jobs); + const int end = ff_slice_pos(height, job + 1, nb_jobs); uint8_t *dst = frame->data[0] + start * frame->linesize[0]; for (int y = start; y < end; y++) { @@ -116,8 +116,8 @@ static int draw_carpet_slice(AVFilterContext *ctx, void *arg, int job, int nb_jo AVFrame *frame = arg; const int width = frame->width; const int height = frame->height; - const int start = (height * job ) / nb_jobs; - const int end = (height * (job+1)) / nb_jobs; + const int start = ff_slice_pos(height, job, nb_jobs); + const int end = ff_slice_pos(height, job + 1, nb_jobs); uint8_t *dst = frame->data[0] + start * frame->linesize[0]; for (int y = start; y < end; y++) { diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c index 697b94d4e8..1beb7d7e4a 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -2131,8 +2131,8 @@ static int zoneplate_fill_slice_##name(AVFilterContext *ctx, \ const int ky = test->ky, kx = test->kx, kxy = test->kxy; \ const int lut_mask = (1 << test->lut_precision) - 1; \ const int nkt2t = kt2 * t * t, nktt = kt * t; \ - const int start = (h * job ) / nb_jobs; \ - const int end = (h * (job+1)) / nb_jobs; \ + const int start = ff_slice_pos(h, job, nb_jobs); \ + const int end = ff_slice_pos(h, job + 1, nb_jobs); \ const ptrdiff_t ylinesize = frame->linesize[0] / sizeof(type); \ const ptrdiff_t ulinesize = frame->linesize[1] / sizeof(type); \ const ptrdiff_t vlinesize = frame->linesize[2] / sizeof(type); \ -- 2.54.0 >From ca98b587f9c7cc80213a34d3cfb2cf4224b1bd36 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Thu, 15 Oct 2026 04:58:55 +0200 Subject: [PATCH 10/12] avformat/idroqdec: continue after the declared size of the first RoQ_INFO chunk Stream desynchronization Replicated through UnModified FFmpeg Found during review of the fixes for the security report yyLBi9GsHV9w Signed-off-by: Michael Niedermayer <[email protected]> --- libavformat/idroqdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/idroqdec.c b/libavformat/idroqdec.c index ad904b42b4..c67724b128 100644 --- a/libavformat/idroqdec.c +++ b/libavformat/idroqdec.c @@ -139,7 +139,7 @@ static int roq_read_packet(AVFormatContext *s, return ret; st->codecpar->width = roq->width = AV_RL16(preamble); st->codecpar->height = roq->height = AV_RL16(preamble + 2); - break; + chunk_size -= RoQ_CHUNK_PREAMBLE_SIZE; } /* don't care about this chunk anymore */ avio_skip(pb, chunk_size); -- 2.54.0 >From ea4bfd207d9cd7b8b88dbb14c188223f3bd135ee Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Thu, 15 Oct 2026 05:00:32 +0200 Subject: [PATCH 11/12] avfilter/vf_stack: reject a grid with more than INT_MAX cells Regression since: aa8905a1b1 NULL pointer dereference Replicated through UnModified FFmpeg with ASAN Found during review of the fixes for the security report GIRN0tvt58WQ Signed-off-by: Michael Niedermayer <[email protected]> --- libavfilter/vf_stack.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c index 19c4b2c147..04a335858b 100644 --- a/libavfilter/vf_stack.c +++ b/libavfilter/vf_stack.c @@ -116,8 +116,11 @@ static av_cold int init(AVFilterContext *ctx) } } - if (is_grid) + if (is_grid) { + if (s->nb_grid_rows > INT_MAX / s->nb_grid_columns) + return AVERROR(EINVAL); s->nb_inputs = s->nb_grid_rows * s->nb_grid_columns; + } } s->frames = av_calloc(s->nb_inputs, sizeof(*s->frames)); -- 2.54.0 >From 4531bc72cbeb956e33c92efbeecb519080cc872a Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Thu, 15 Oct 2026 15:51:52 +0200 Subject: [PATCH 12/12] avfilter/vf_codecview: compute the arrow head length in 64bit Fixes: division by zero Fixes: signed integer overflow Fixes: NaN to int conversion Fixes: 2qHh10XPbgiO Fixes: swarm-Signed-integer-overflow-in-draw_arrow-length-calc-8f1f15 Division by zero Replicated through UnModified FFmpeg with ASAN Signed integer overflow Replicated through UnModified FFmpeg with UBSAN NaN to int conversion Replicated through UnModified FFmpeg with UBSAN Found-by: zhang xingxing <[email protected]> The report suggested doing the shift in a wider unsigned type. Signed-off-by: Michael Niedermayer <[email protected]> --- libavfilter/vf_codecview.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_codecview.c b/libavfilter/vf_codecview.c index f20056b91b..cd445e4e9c 100644 --- a/libavfilter/vf_codecview.c +++ b/libavfilter/vf_codecview.c @@ -190,7 +190,7 @@ static void draw_arrow(uint8_t *buf, int sx, int sy, int ex, if (dx * dx + dy * dy > 3 * 3) { int rx = dx + dy; int ry = -dx + dy; - int length = sqrt((rx * rx + ry * ry) << 8); + int length = sqrt((rx * (int64_t)rx + ry * (int64_t)ry) << 8); // FIXME subpixel accuracy rx = ROUNDED_DIV(rx * (3 << 4), length); -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
