PR #24496 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24496 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24496.patch
Fixes: NULL pointer dereference Fixes: 5cNIJSj1u1Lc/input.bin Fixes: 5cNIJSj1u1Lc Found-by: Zheng Yu <[email protected]> >From 1986d8c07c1cda6680b71bf41e1ae13f22fea840 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 14 Sep 2026 03:37:23 +0200 Subject: [PATCH 1/3] avcodec/cfhd: check the channel number after every tag Fixes: NULL pointer dereference Fixes: 5cNIJSj1u1Lc/input.bin Fixes: 5cNIJSj1u1Lc Found-by: Zheng Yu <[email protected]> --- libavcodec/cfhd.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c index 128362ac62..13a62bdb55 100644 --- a/libavcodec/cfhd.c +++ b/libavcodec/cfhd.c @@ -433,11 +433,6 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic, } else if (tag == ChannelNumber) { s->channel_num = data; av_log(avctx, AV_LOG_DEBUG, "Channel number %"PRIu16"\n", data); - if (s->channel_num >= s->planes) { - av_log(avctx, AV_LOG_ERROR, "Invalid channel number\n"); - ret = AVERROR(EINVAL); - goto end; - } init_plane_defaults(s); } else if (tag == SubbandNumber) { if (s->subband_num != 0 && data == 1 && (s->transform_type == 0 || s->transform_type == 2)) // hack @@ -631,6 +626,12 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic, } else av_log(avctx, AV_LOG_DEBUG, "Unknown tag %i data %x\n", tag, data); + if (s->channel_num >= s->planes) { + av_log(avctx, AV_LOG_ERROR, "Invalid channel number\n"); + ret = AVERROR(EINVAL); + goto end; + } + if (tag == BitstreamMarker && data == CoefficientSegment && s->coded_format != AV_PIX_FMT_NONE) { int lowpass_height = s->plane[s->channel_num].band[0][0].height; -- 2.52.0 >From c761c4849cbded98a8286e4c3fe4f4fa6a914c84 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 14 Sep 2026 03:38:39 +0200 Subject: [PATCH 2/3] avcodec/cfhd: reject header tags after the frame buffer was allocated Found during triage of the security report Fixes: NULL pointer dereference Fixes: 5cNIJSj1u1Lc/input-format-after-header.bin / gen-format-after-header.py Fixes: 5cNIJSj1u1Lc --- libavcodec/cfhd.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c index 13a62bdb55..7c8af2647c 100644 --- a/libavcodec/cfhd.c +++ b/libavcodec/cfhd.c @@ -632,6 +632,12 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic, goto end; } + if (got_buffer && (s->coded_width || s->coded_height || s->coded_format != AV_PIX_FMT_NONE)) { + av_log(avctx, AV_LOG_ERROR, "Header tag after end of header\n"); + ret = AVERROR(EINVAL); + goto end; + } + if (tag == BitstreamMarker && data == CoefficientSegment && s->coded_format != AV_PIX_FMT_NONE) { int lowpass_height = s->plane[s->channel_num].band[0][0].height; @@ -919,8 +925,7 @@ finish: ff_thread_finish_setup(avctx); if (!s->a_width || !s->a_height || s->a_format == AV_PIX_FMT_NONE || - s->a_transform_type == INT_MIN || - s->coded_width || s->coded_height || s->coded_format != AV_PIX_FMT_NONE) { + s->a_transform_type == INT_MIN) { av_log(avctx, AV_LOG_ERROR, "Invalid dimensions\n"); ret = AVERROR(EINVAL); goto end; -- 2.52.0 >From 7c08c96f39f40be484a16205320660c2b48ed399 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 15 Sep 2026 04:00:34 +0200 Subject: [PATCH 3/3] avcodec/cfhd: reset the allocated band sizes when freeing the buffers Found during review of the fix for the security report Fixes: NULL pointer dereference Fixes: 5cNIJSj1u1Lc/input-frameindex-path.bin / gen-frameindex-path.py Fixes: 5cNIJSj1u1Lc --- libavcodec/cfhd.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c index 7c8af2647c..e91788d4a8 100644 --- a/libavcodec/cfhd.c +++ b/libavcodec/cfhd.c @@ -227,10 +227,11 @@ static void free_buffers(CFHDContext *s) s->plane[i].l_h[j] = NULL; for (int j = 0; j < DWT_LEVELS_3D; j++) - p->band[j][0].read_ok = - p->band[j][1].read_ok = - p->band[j][2].read_ok = - p->band[j][3].read_ok = 0; + for (unsigned k = 0; k < FF_ARRAY_ELEMS(p->band[j]); k++) { + p->band[j][k].a_width = 0; + p->band[j][k].a_height = 0; + p->band[j][k].read_ok = 0; + } } s->a_height = 0; s->a_width = 0; -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
