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]

Reply via email to