Commit 4170a213c9 for ffmpeg
commit 4170a213c9af85cc08b3daabbd87b7438eb397ff
Author: Michael Niedermayer <michael@niedermayer.cc>
Date: Wed Nov 11 23:33:29 2026 +0100
avfilter/af_dynaudnorm: apply a new frame length and overlap before taking the next frame
Fixes: out of array write
Fixes: negative size memset
Fixes: FSTVpORbTPVr
Regression since: 456d48c752
Found during the triage of a finding from the review of https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25800
Out of array write and negative size memset Replicated through UnModified FFmpeg with ASAN
diff --git a/libavfilter/af_dynaudnorm.c b/libavfilter/af_dynaudnorm.c
index 98a3bb91e5..1af6a3ed9f 100644
--- a/libavfilter/af_dynaudnorm.c
+++ b/libavfilter/af_dynaudnorm.c
@@ -936,7 +936,7 @@ static int activate(AVFilterContext *ctx)
AVFilterLink *outlink = ctx->outputs[0];
DynamicAudioNormalizerContext *s = ctx->priv;
AVFrame *in = NULL;
- int ret = 0, status;
+ int ret = 0, status, frame_len;
int64_t pts;
ret = av_channel_layout_copy(&s->ch_layout, &inlink->ch_layout);
@@ -947,6 +947,19 @@ static int activate(AVFilterContext *ctx)
FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
+ frame_len = frame_size(inlink->sample_rate, s->frame_len_msec);
+ if (frame_len < 0)
+ return frame_len;
+ if (frame_len != s->frame_len) {
+ AVFrame *window = ff_get_audio_buffer(outlink, frame_len * 2);
+ if (!window)
+ return AVERROR(ENOMEM);
+ av_frame_free(&s->window);
+ s->window = window;
+ s->frame_len = frame_len;
+ }
+ s->sample_advance = FFMAX(1, lrint(s->frame_len * (1. - s->overlap)));
+
if (!s->eof) {
ret = ff_inlink_consume_samples(inlink, s->sample_advance, s->sample_advance, &in);
if (ret < 0)
@@ -986,9 +999,8 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar
char *res, int res_len, int flags)
{
DynamicAudioNormalizerContext *s = ctx->priv;
- AVFilterLink *inlink = ctx->inputs[0];
int prev_filter_size = s->filter_size;
- int frame_len, ret;
+ int ret;
ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
if (ret < 0)
@@ -1005,18 +1017,6 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar
}
}
- frame_len = frame_size(inlink->sample_rate, s->frame_len_msec);
- if (frame_len < 0)
- return frame_len;
- if (frame_len != s->frame_len) {
- AVFrame *window = ff_get_audio_buffer(ctx->outputs[0], frame_len * 2);
- if (!window)
- return AVERROR(ENOMEM);
- av_frame_free(&s->window);
- s->window = window;
- s->frame_len = frame_len;
- }
- s->sample_advance = FFMAX(1, lrint(s->frame_len * (1. - s->overlap)));
if (s->expr_str) {
ret = av_expr_parse(&s->expr, s->expr_str, var_names, NULL, NULL,
NULL, NULL, 0, ctx);