PR #23190 opened by toots
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23190
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23190.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 a981a06fe799556944ecbd51272c8f99b8c5c506 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 e528fd1f41..4cc55c2e77 100644
--- a/libavformat/oggparsecelt.c
+++ b/libavformat/oggparsecelt.c
@@ -26,6 +26,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;
 };
@@ -61,6 +64,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]

Reply via email to