* [FFmpeg-devel] [PR] avcodec/cfhd: Check transform type before continuing (PR #21759)
@ 2026-02-15 3:35 michaelni via ffmpeg-devel
0 siblings, 0 replies; only message in thread
From: michaelni via ffmpeg-devel @ 2026-02-15 3:35 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: michaelni
PR #21759 opened by michaelni
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21759
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21759.patch
avcodec/cfhd: Check transform type before continuing.
Fixes: null pointer dereference
Fixes: 471768165/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_CFHD_DEC_fuzzer-6187504467509248
The first frame allocates buffers with one transform type
the second frame sets up another transform type but the code to reallocate buffers is never triggered
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
>From 56c7b802d04419f56ce577f9d9d1d06a7ba9c287 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <michael@niedermayer.cc>
Date: Sat, 14 Feb 2026 23:00:02 +0100
Subject: [PATCH 1/2] avcodec/cfhd: Add CFHDSegment enum and named identifiers
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavcodec/cfhd.c | 4 ++--
libavcodec/cfhd.h | 9 +++++++++
libavcodec/cfhdenc.c | 12 ++++++------
3 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c
index f110b91f0b..6d1cf4b67b 100644
--- a/libavcodec/cfhd.c
+++ b/libavcodec/cfhd.c
@@ -631,7 +631,7 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
} else
av_log(avctx, AV_LOG_DEBUG, "Unknown tag %i data %x\n", tag, data);
- if (tag == BitstreamMarker && data == 0xf0f &&
+ if (tag == BitstreamMarker && data == CoefficientSegment &&
s->coded_format != AV_PIX_FMT_NONE) {
int lowpass_height = s->plane[s->channel_num].band[0][0].height;
int lowpass_width = s->plane[s->channel_num].band[0][0].width;
@@ -701,7 +701,7 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
coeff_data = s->plane[s->channel_num].subband[s->subband_num_actual];
/* Lowpass coefficients */
- if (tag == BitstreamMarker && data == 0xf0f) {
+ if (tag == BitstreamMarker && data == CoefficientSegment) {
int lowpass_height, lowpass_width, lowpass_a_height, lowpass_a_width;
if (!s->a_width || !s->a_height) {
diff --git a/libavcodec/cfhd.h b/libavcodec/cfhd.h
index 2dbac80c66..880c0e1e9d 100644
--- a/libavcodec/cfhd.h
+++ b/libavcodec/cfhd.h
@@ -91,6 +91,15 @@ enum CFHDParam {
ChannelHeight = 105,
};
+enum CFHDSegment {
+ LowPassSegment = 0x1a4a,
+ LowPassEndSegment = 0x1b4b,
+ HighPassSegment = 0x0d0d,
+ BandSegment = 0x0e0e,
+ HighPassEndSegment = 0x0c0c,
+ CoefficientSegment = 0x0f0f,
+};
+
#define VLC_BITS 9
#define SUBBAND_COUNT 10
#define SUBBAND_COUNT_3D 17
diff --git a/libavcodec/cfhdenc.c b/libavcodec/cfhdenc.c
index 42e01bfd85..db435f321c 100644
--- a/libavcodec/cfhdenc.c
+++ b/libavcodec/cfhdenc.c
@@ -627,7 +627,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
}
bytestream2_put_be16(pby, BitstreamMarker);
- bytestream2_put_be16(pby, 0x1a4a);
+ bytestream2_put_be16(pby, LowPassSegment);
pos = bytestream2_tell_p(pby);
@@ -653,7 +653,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
bytestream2_put_be16(pby, 16);
bytestream2_put_be16(pby, BitstreamMarker);
- bytestream2_put_be16(pby, 0x0f0f);
+ bytestream2_put_be16(pby, CoefficientSegment);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++)
@@ -662,7 +662,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
}
bytestream2_put_be16(pby, BitstreamMarker);
- bytestream2_put_be16(pby, 0x1b4b);
+ bytestream2_put_be16(pby, LowPassEndSegment);
for (int l = 0; l < 3; l++) {
for (int i = 0; i < 3; i++) {
@@ -677,7 +677,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
int height = s->plane[p].band[l][0].height;
bytestream2_put_be16(pby, BitstreamMarker);
- bytestream2_put_be16(pby, 0x0d0d);
+ bytestream2_put_be16(pby, HighPassSegment);
bytestream2_put_be16(pby, WaveletType);
bytestream2_put_be16(pby, 3 + 2 * (l == 2));
@@ -714,7 +714,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
int count = 0, padd = 0;
bytestream2_put_be16(pby, BitstreamMarker);
- bytestream2_put_be16(pby, 0x0e0e);
+ bytestream2_put_be16(pby, BandSegment);
bytestream2_put_be16(pby, SubbandNumber);
bytestream2_put_be16(pby, i + 1);
@@ -783,7 +783,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
}
bytestream2_put_be16(pby, BitstreamMarker);
- bytestream2_put_be16(pby, 0x0c0c);
+ bytestream2_put_be16(pby, HighPassEndSegment);
}
s->plane[p].size = bytestream2_tell_p(pby) - pos;
--
2.52.0
>From 0b97c9938e518fd03ef8699e86d60773ec1a6010 Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <michael@niedermayer.cc>
Date: Sun, 15 Feb 2026 00:00:55 +0100
Subject: [PATCH 2/2] avcodec/cfhd: Check transform type before continuing
Fixes: null pointer dereference
Fixes: 471768165/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_CFHD_DEC_fuzzer-6187504467509248
The first frame allocates buffers with one transform type
the second frame sets up another transform type but the code to reallocate buffers is never triggered
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
libavcodec/cfhd.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c
index 6d1cf4b67b..4d430e32ef 100644
--- a/libavcodec/cfhd.c
+++ b/libavcodec/cfhd.c
@@ -698,6 +698,11 @@ static int cfhd_decode(AVCodecContext *avctx, AVFrame *pic,
if (s->subband_num_actual == 255)
goto finish;
+
+ if (tag == BitstreamMarker && data == CoefficientSegment || tag == BandHeader || tag == BandSecondPass || s->peak.level)
+ if (s->transform_type != s->a_transform_type)
+ return AVERROR_PATCHWELCOME;
+
coeff_data = s->plane[s->channel_num].subband[s->subband_num_actual];
/* Lowpass coefficients */
--
2.52.0
_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-02-15 3:35 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-15 3:35 [FFmpeg-devel] [PR] avcodec/cfhd: Check transform type before continuing (PR #21759) michaelni via ffmpeg-devel
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git