PR #25059 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25059 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25059.patch
>From f75e0bb08fae21aeca4fed59bdce78959f090ba6 Mon Sep 17 00:00:00 2001 From: zhang xingxing <[email protected]> Date: Tue, 13 Oct 2026 06:39:23 +0200 Subject: [PATCH 1/9] avfilter/vf_unsharp: initialize the alpha filter parameters Fixes: NULL pointer dereference Fixes: cRljeq44cXxS Fixes: swarm-Null-deref-when-sharpening-alpha-plane-a2779b Regression since: 84f5583078 NULL pointer dereference Replicated through UnModified FFmpeg with ASAN Found-by: zhang xingxing <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> --- libavfilter/vf_unsharp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c index 6d2be4328d..85f451c82c 100644 --- a/libavfilter/vf_unsharp.c +++ b/libavfilter/vf_unsharp.c @@ -310,7 +310,7 @@ static int config_input(AVFilterLink *inlink) if (ret < 0) return ret; - return 0; + return init_filter_param(inlink->dst, &s->alpha, "alpha", inlink->w); } static void free_filter_param(UnsharpFilterParam *fp, int nb_threads) @@ -331,6 +331,7 @@ static av_cold void uninit(AVFilterContext *ctx) free_filter_param(&s->luma, s->nb_threads); free_filter_param(&s->chroma, s->nb_threads); + free_filter_param(&s->alpha, s->nb_threads); } static int filter_frame(AVFilterLink *link, AVFrame *in) -- 2.52.0 >From 8564e4e7fdc0d814589c3593df1e3fd2df626c56 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:39:23 +0200 Subject: [PATCH 2/9] avfilter/vf_atadenoise: filter the 4th plane with its own thresholds and sigma Fixes: NULL pointer dereference Fixes: xIzHmB8ju8Nq Fixes: swarm-NULL-dereference-on-YUVA-alpha-plane-filter-5f974b Regression since: a50bd3a50e NULL pointer dereference Replicated through UnModified FFmpeg with ASAN Found-by: zhang xingxing <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> --- doc/filters.texi | 11 ++++++++++- libavfilter/vf_atadenoise.c | 23 ++++++++++------------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 04496d338f..9eeb5fdcd3 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -8689,6 +8689,14 @@ Valid range is 0 to 0.3. Set threshold B for 3rd plane. Default is 0.04. Valid range is 0 to 5. +@item 3a +Set threshold A for 4th plane. Default is 0.02. +Valid range is 0 to 0.3. + +@item 3b +Set threshold B for 4th plane. Default is 0.04. +Valid range is 0 to 5. + Threshold A is designed to react on abrupt changes in the input signal and threshold B is designed to react on continuous changes in the input signal. @@ -8710,7 +8718,8 @@ will continue processing other side of frames if they are equal or below thresho @item 0s @item 1s @item 2s -Set sigma for 1st plane, 2nd plane or 3rd plane. Default is 32767. +@item 3s +Set sigma for 1st plane, 2nd plane, 3rd plane or 4th plane. Default is 32767. Valid range is from 0 to 32767. This options controls weight for each pixel in radius defined by size. Default value means every pixel have same weight. diff --git a/libavfilter/vf_atadenoise.c b/libavfilter/vf_atadenoise.c index 7773df5615..9e2bee1ce5 100644 --- a/libavfilter/vf_atadenoise.c +++ b/libavfilter/vf_atadenoise.c @@ -76,6 +76,8 @@ static const AVOption atadenoise_options[] = { { "1b", "set threshold B for 2nd plane", OFFSET(fthrb[1]), AV_OPT_TYPE_FLOAT, {.dbl=0.04}, 0, 5.0, FLAGS }, { "2a", "set threshold A for 3rd plane", OFFSET(fthra[2]), AV_OPT_TYPE_FLOAT, {.dbl=0.02}, 0, 0.3, FLAGS }, { "2b", "set threshold B for 3rd plane", OFFSET(fthrb[2]), AV_OPT_TYPE_FLOAT, {.dbl=0.04}, 0, 5.0, FLAGS }, + { "3a", "set threshold A for 4th plane", OFFSET(fthra[3]), AV_OPT_TYPE_FLOAT, {.dbl=0.02}, 0, 0.3, FLAGS }, + { "3b", "set threshold B for 4th plane", OFFSET(fthrb[3]), AV_OPT_TYPE_FLOAT, {.dbl=0.04}, 0, 5.0, FLAGS }, { "s", "set how many frames to use", OFFSET(size), AV_OPT_TYPE_INT, {.i64=9}, 5, SIZE, VF }, { "p", "set what planes to filter", OFFSET(planes), AV_OPT_TYPE_FLAGS, {.i64=7}, 0, 15, FLAGS }, { "a", "set variant of algorithm", OFFSET(algorithm),AV_OPT_TYPE_INT, {.i64=PARALLEL}, 0, NB_ATAA-1, FLAGS, .unit = "a" }, @@ -84,6 +86,7 @@ static const AVOption atadenoise_options[] = { { "0s", "set sigma for 1st plane", OFFSET(sigma[0]), AV_OPT_TYPE_FLOAT, {.dbl=INT16_MAX}, 0, INT16_MAX, FLAGS }, { "1s", "set sigma for 2nd plane", OFFSET(sigma[1]), AV_OPT_TYPE_FLOAT, {.dbl=INT16_MAX}, 0, INT16_MAX, FLAGS }, { "2s", "set sigma for 3rd plane", OFFSET(sigma[2]), AV_OPT_TYPE_FLOAT, {.dbl=INT16_MAX}, 0, INT16_MAX, FLAGS }, + { "3s", "set sigma for 4th plane", OFFSET(sigma[3]), AV_OPT_TYPE_FLOAT, {.dbl=INT16_MAX}, 0, INT16_MAX, FLAGS }, { NULL } }; @@ -409,16 +412,12 @@ static int config_input(AVFilterLink *inlink) s->dsp.filter_row[p] = s->algorithm == PARALLEL ? fweight_row16 : fweight_row16_serial; } - s->thra[0] = s->fthra[0] * (1 << depth) - 1; - s->thra[1] = s->fthra[1] * (1 << depth) - 1; - s->thra[2] = s->fthra[2] * (1 << depth) - 1; - s->thrb[0] = s->fthrb[0] * (1 << depth) - 1; - s->thrb[1] = s->fthrb[1] * (1 << depth) - 1; - s->thrb[2] = s->fthrb[2] * (1 << depth) - 1; - for (int p = 0; p < s->nb_planes; p++) { float sigma = s->radius * s->sigma[p]; + s->thra[p] = s->fthra[p] * (1 << depth) - 1; + s->thrb[p] = s->fthrb[p] * (1 << depth) - 1; + s->weights[p][s->radius] = 1.f; for (int n = 1; n <= s->radius; n++) { s->weights[p][s->radius + n] = @@ -473,12 +472,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) for (i = 0; i < s->size; i++) { AVFrame *frame = ff_bufqueue_peek(&s->q, i); - s->data[0][i] = frame->data[0]; - s->data[1][i] = frame->data[1]; - s->data[2][i] = frame->data[2]; - s->linesize[0][i] = frame->linesize[0]; - s->linesize[1][i] = frame->linesize[1]; - s->linesize[2][i] = frame->linesize[2]; + for (int p = 0; p < s->nb_planes; p++) { + s->data[p][i] = frame->data[p]; + s->linesize[p][i] = frame->linesize[p]; + } } td.in = in; td.out = out; -- 2.52.0 >From c50b55930460b85b54b277143b5c135c224b0479 Mon Sep 17 00:00:00 2001 From: zhang xingxing <[email protected]> Date: Tue, 13 Oct 2026 06:39:23 +0200 Subject: [PATCH 3/9] avfilter/vf_crop: keep the x/y expressions when the new ones fail to parse This is not a security issue. Fixes: 3yfFBPXxhEts Fixes: swarm-NULL-pexpr-dereference-after-failed-x-y-runtime-reconfiguration-e3e672 Regression since: d2b78fe6b7 NULL pointer dereference Replicated through UnModified FFmpeg with ASAN Found-by: zhang xingxing <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> --- libavfilter/vf_crop.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c index e06be77302..f25e0564aa 100644 --- a/libavfilter/vf_crop.c +++ b/libavfilter/vf_crop.c @@ -225,17 +225,21 @@ fail_expr: static int config_input(AVFilterLink *link) { CropContext *s = link->dst->priv; + AVExpr *x_pexpr = NULL, *y_pexpr = NULL; s->var_values[VAR_X] = NAN; s->var_values[VAR_Y] = NAN; + if (av_expr_parse(&x_pexpr, s->x_expr, var_names, + NULL, NULL, NULL, NULL, 0, link->dst) < 0 || + av_expr_parse(&y_pexpr, s->y_expr, var_names, + NULL, NULL, NULL, NULL, 0, link->dst) < 0) { + av_expr_free(x_pexpr); + return AVERROR(EINVAL); + } av_expr_free(s->x_pexpr); av_expr_free(s->y_pexpr); - s->x_pexpr = s->y_pexpr = NULL; - if (av_expr_parse(&s->x_pexpr, s->x_expr, var_names, - NULL, NULL, NULL, NULL, 0, link->dst) < 0 || - av_expr_parse(&s->y_pexpr, s->y_expr, var_names, - NULL, NULL, NULL, NULL, 0, link->dst) < 0) - return AVERROR(EINVAL); + s->x_pexpr = x_pexpr; + s->y_pexpr = y_pexpr; return config_crop_area(link); } -- 2.52.0 >From e563c17f95694485728655a90d0cff8eb130509b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:39:23 +0200 Subject: [PATCH 4/9] avcodec/decode: use avcodec_get_hw_config() in avcodec_default_get_format() This is not a security issue. Fixes: e5BUoyG1Jo3N Fixes: swarm-NULL-pointer-dereference-in-hw_configs-iteration-0b77cc Regression since: 67e81d79cc NULL pointer member access Replicated through API with UBSAN Found-by: zhang xingxing <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> --- libavcodec/decode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 627ad9420a..96da70fb7e 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -1019,7 +1019,7 @@ enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *avctx, AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)avctx->hw_device_ctx->data; for (i = 0;; i++) { - config = &ffcodec(avctx->codec)->hw_configs[i]->public; + config = avcodec_get_hw_config(avctx->codec, i); if (!config) break; if (!(config->methods & -- 2.52.0 >From e766542a13cf3846d29cc3c8107aab6c465d1135 Mon Sep 17 00:00:00 2001 From: zhang xingxing <[email protected]> Date: Tue, 13 Oct 2026 06:39:23 +0200 Subject: [PATCH 5/9] avformat/rtmpproto: reject a llnw authentication challenge without a nonce This is not a security issue. Fixes: 6lFLlG49gRxf Fixes: swarm-NULL-pointer-dereference-via-snprintf-s-with-NULL-nonce-83e8f3 Regression since: c1ea44c54d NULL nonce passed to snprintf() Replicated through UnModified FFmpeg with a local RTMP server (the reconnect carried nonce=(null)) Found-by: zhang xingxing <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> --- libavformat/rtmpproto.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 785455e06d..392c559090 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -1760,8 +1760,7 @@ static int do_llnw_auth(RTMPContext *rt, const char *user, const char *nonce) av_md5_init(md5); av_md5_update(md5, hashstr1, strlen(hashstr1)); av_md5_update(md5, ":", 1); - if (nonce) - av_md5_update(md5, nonce, strlen(nonce)); + av_md5_update(md5, nonce, strlen(nonce)); av_md5_update(md5, ":", 1); av_md5_update(md5, nc, strlen(nc)); av_md5_update(md5, ":", 1); @@ -1864,6 +1863,10 @@ static int handle_connect_error(URLContext *s, const char *desc) if ((ret = do_adobe_auth(rt, user, salt, opaque, challenge)) < 0) return ret; } else { + if (!nonce) { + av_log(s, AV_LOG_ERROR, "No nonce in the llnw authentication challenge\n"); + return AVERROR_UNKNOWN; + } if ((ret = do_llnw_auth(rt, user, nonce)) < 0) return ret; } -- 2.52.0 >From 6753c616462439e603e93233e91e13c75063526e Mon Sep 17 00:00:00 2001 From: zhang xingxing <[email protected]> Date: Tue, 13 Oct 2026 06:39:23 +0200 Subject: [PATCH 6/9] avformat/rtmpdh: fail bn_hex2bn() when bn_new() fails with GMP and mbedTLS This is not a security issue. Fixes: d9RoImPBG3x8 Fixes: swarm-NULL-q1-passed-to-bn_modexp-when-GMP-MbedTLS-alloc-fails-c4db13 Regression since: 78efc69e7c (GMP), 62f5c9d68b (mbedTLS) NULL bignum passed to bn_modexp() Replicated through Modified FFmpeg with ASAN (GMP and mbedTLS builds, the q1 allocation in ff_dh_generate_public_key() made to fail) Found-by: zhang xingxing <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> --- libavformat/rtmpdh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/rtmpdh.c b/libavformat/rtmpdh.c index 6a6c2ccd87..fb7aaf07c0 100644 --- a/libavformat/rtmpdh.c +++ b/libavformat/rtmpdh.c @@ -95,7 +95,7 @@ if (bn) \ ret = (mpz_set_str(bn, buf, 16) == 0); \ else \ - ret = 1; \ + ret = 0; \ } while (0) #define bn_random(bn, num_bits) \ do { \ @@ -198,7 +198,7 @@ static int bn_modexp(FFBigNum bn, FFBigNum y, FFBigNum q, FFBigNum p) if (bn) \ ret = (mbedtls_mpi_read_string(bn, 16, buf) == 0); \ else \ - ret = 1; \ + ret = 0; \ } while (0) #define bn_random(bn, num_bits) \ do { \ -- 2.52.0 >From 93e5d114204b8a154e5f6765810fc5db2074ed43 Mon Sep 17 00:00:00 2001 From: zhang xingxing <[email protected]> Date: Tue, 13 Oct 2026 06:39:23 +0200 Subject: [PATCH 7/9] avcodec/mediacodecdec: escape a 00 00 0x sequence ending on the last byte of a parameter set This is not a security issue. Fixes: D8dV7mhIc12c Fixes: swarm-Off-by-one-error-in-NALU-escape-loop-459f43 Regression since: 88d9c30cf5 Verified with h2645_ps_to_nalu() compiled standalone; the decoder itself was not run (Android only) Found-by: zhang xingxing <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> --- libavcodec/mediacodecdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/mediacodecdec.c b/libavcodec/mediacodecdec.c index 89f8ed54a8..0551370a54 100644 --- a/libavcodec/mediacodecdec.c +++ b/libavcodec/mediacodecdec.c @@ -99,7 +99,7 @@ static int h2645_ps_to_nalu(const uint8_t *src, int src_size, uint8_t **out, int /* Escape 0x00, 0x00, 0x0{0-3} pattern */ for (i = 4; i < *out_size; i++) { - if (i < *out_size - 3 && + if (i < *out_size - 2 && p[i + 0] == 0 && p[i + 1] == 0 && p[i + 2] <= 3) { -- 2.52.0 >From 8244474c6442d3fa0e448b8dc9a186c0c95c7c69 Mon Sep 17 00:00:00 2001 From: zhang xingxing <[email protected]> Date: Tue, 13 Oct 2026 06:40:15 +0200 Subject: [PATCH 8/9] avfilter/vf_libvmaf: reject a feature config without a name This is not a security issue. Fixes: 1QLxiyziAd9N Fixes: swarm-NULL-feature_name-dereferenced-in-parse_features-129e69 Regression since: 3d29724c00 NULL feature name Replicated through UnModified FFmpeg (the error message read "(null)") Found-by: zhang xingxing <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> --- libavfilter/vf_libvmaf.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/libavfilter/vf_libvmaf.c b/libavfilter/vf_libvmaf.c index 3ab67d3dba..4771541664 100644 --- a/libavfilter/vf_libvmaf.c +++ b/libavfilter/vf_libvmaf.c @@ -239,30 +239,36 @@ static int parse_features(AVFilterContext *ctx) } for (unsigned i = 0; i < dict_cnt; i++) { - char *feature_name = NULL; + const AVDictionaryEntry *name = av_dict_get(dict[i], "name", NULL, + AV_DICT_MATCH_CASE); VmafFeatureDictionary *feature_opts_dict = NULL; const AVDictionaryEntry *e = NULL; + if (!name) { + av_log(ctx, AV_LOG_ERROR, "feature without a name: %s\n", + s->feature_cfg); + err = AVERROR(EINVAL); + goto exit; + } + while (e = av_dict_iterate(dict[i], e)) { - if (!strcmp(e->key, "name")) { - feature_name = e->value; + if (!strcmp(e->key, "name")) continue; - } err = vmaf_feature_dictionary_set(&feature_opts_dict, e->key, e->value); if (err) { av_log(ctx, AV_LOG_ERROR, "could not set feature option: %s.%s=%s\n", - feature_name, e->key, e->value); + name->value, e->key, e->value); goto exit; } } - err = vmaf_use_feature(s->vmaf, feature_name, feature_opts_dict); + err = vmaf_use_feature(s->vmaf, name->value, feature_opts_dict); if (err) { av_log(ctx, AV_LOG_ERROR, - "problem during vmaf_use_feature: %s\n", feature_name); + "problem during vmaf_use_feature: %s\n", name->value); goto exit; } } -- 2.52.0 >From 8c2a8f7a151f0157c77f7c9df62743fbda8a06fc Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 13 Oct 2026 06:40:15 +0200 Subject: [PATCH 9/9] avcodec/nvdec: attach the hw_frames_ctx before the unmap buffer owns the mapped frame This is not a security issue. Fixes: DPSu3J80jQZN Fixes: swarm-NULL-deref-in-nvdec_unmap_mapped_frame-when-av_buffer_replace-fails-5c28b7 Regression since: 767f53533a NULL pointer dereference Replicated through Modified FFmpeg with ASAN (av_buffer_replace() made to fail for one frame) Found-by: zhang xingxing <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> --- libavcodec/nvdec.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/libavcodec/nvdec.c b/libavcodec/nvdec.c index f0ae2130c2..d2c176e4f9 100644 --- a/libavcodec/nvdec.c +++ b/libavcodec/nvdec.c @@ -922,6 +922,10 @@ static int nvdec_retrieve_data(void *logctx, AVFrame *frame) if (ret < 0) goto finish; + ret = av_buffer_replace(&frame->hw_frames_ctx, decoder->real_hw_frames_ref); + if (ret < 0) + goto copy_fail; + unmap_data = av_mallocz(sizeof(*unmap_data)); if (!unmap_data) { ret = AVERROR(ENOMEM); @@ -936,10 +940,6 @@ static int nvdec_retrieve_data(void *logctx, AVFrame *frame) goto copy_fail; } - ret = av_buffer_replace(&frame->hw_frames_ctx, decoder->real_hw_frames_ref); - if (ret < 0) - goto copy_fail; - unmap_data->idx = cf->idx; unmap_data->decoder = av_refstruct_ref(cf->decoder); @@ -953,12 +953,8 @@ static int nvdec_retrieve_data(void *logctx, AVFrame *frame) goto finish; copy_fail: - if (!frame->buf[1]) { - CHECK_CU(decoder->cvdl->cuvidUnmapVideoFrame(decoder->decoder, devptr)); - av_freep(&unmap_data); - } else { - av_buffer_unref(&frame->buf[1]); - } + CHECK_CU(decoder->cvdl->cuvidUnmapVideoFrame(decoder->decoder, devptr)); + av_freep(&unmap_data); finish: CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy)); -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
