PR #23189 opened by toots URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23189 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23189.patch
celt_header() reads a uint32 `extra_headers` field from the CELT identification header and stores `1 + extra_headers` into the signed int extra_headers_left. With extra_headers = 0x7FFFFFFE this becomes INT_MAX and the OGG parser consumes every subsequent page as a CELT "extra header" without ever reaching audio data, hanging on any streaming input. A value of 0xFFFFFFFE wraps the signed addition negative, with the same family of consequences. Reject any extra_headers count above a small fixed cap (16, well above any real CELT-over-Ogg stream). Verified with the audit PoC (a crafted file plus an infinite-page FIFO): without the patch, ffmpeg consumes pages forever; with the patch it logs "Too many CELT extra headers (...)" and exits in ~70 ms with AVERROR_INVALIDDATA. Reported by Franciszek Kalinowski (isec.pl / striga.ai) and Bartosz Smigielski. (cherry picked from commit 87439ed6195ed1eb079bc41f3a7a196438275aac) >From 181cfa10080cc4a902e9fda7580fdd2c6f29068a Mon Sep 17 00:00:00 2001 From: Franciszek Kalinowski <[email protected]> Date: Tue, 19 May 2026 09:41:42 +0200 Subject: [PATCH] avformat/oggparsecelt: bound extra_headers to avoid an effectively infinite loop celt_header() reads a uint32 `extra_headers` field from the CELT identification header and stores `1 + extra_headers` into the signed int extra_headers_left. With extra_headers = 0x7FFFFFFE this becomes INT_MAX and the OGG parser consumes every subsequent page as a CELT "extra header" without ever reaching audio data, hanging on any streaming input. A value of 0xFFFFFFFE wraps the signed addition negative, with the same family of consequences. Reject any extra_headers count above a small fixed cap (16, well above any real CELT-over-Ogg stream). Verified with the audit PoC (a crafted file plus an infinite-page FIFO): without the patch, ffmpeg consumes pages forever; with the patch it logs "Too many CELT extra headers (...)" and exits in ~70 ms with AVERROR_INVALIDDATA. Reported by Franciszek Kalinowski (isec.pl / striga.ai) and Bartosz Smigielski. (cherry picked from commit 87439ed6195ed1eb079bc41f3a7a196438275aac) --- libavformat/oggparsecelt.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libavformat/oggparsecelt.c b/libavformat/oggparsecelt.c index 626e1ab27d..61ce8ada38 100644 --- a/libavformat/oggparsecelt.c +++ b/libavformat/oggparsecelt.c @@ -27,6 +27,9 @@ #include "internal.h" #include "oggdec.h" +/* CELT-over-Ogg streams use at most a couple of vorbiscomment "extra" headers. */ +#define CELT_MAX_EXTRA_HEADERS 16 + struct oggcelt_private { int extra_headers_left; }; @@ -62,6 +65,12 @@ static int celt_header(AVFormatContext *s, int idx) overlap = AV_RL32(p + 48); /* unused bytes per packet field skipped */ extra_headers = AV_RL32(p + 56); + if (extra_headers > CELT_MAX_EXTRA_HEADERS) { + av_log(s, AV_LOG_ERROR, + "Too many CELT extra headers (%u)\n", extra_headers); + av_free(priv); + return AVERROR_INVALIDDATA; + } st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->codec_id = AV_CODEC_ID_CELT; st->codecpar->sample_rate = sample_rate; -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
