PR #23176 opened by michaelni
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23176
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23176.patch

rtsp_read_announce() reads Content-Length from the RTSP request and passes
it directly to av_malloc() without any upper-bound check. An attacker who
can talk to an RTSP listener (`ffmpeg -rtsp_flags listen ...`) can request
an arbitrary allocation size with a single ANNOUNCE header. Repeating it
exhausts memory, and Content-Length: INT_MAX overflows content_length+1
to 0 and turns into an undersized buffer + large read.

Cap content_length at 64 KiB (more than any realistic SDP) before the
av_malloc() and reject anything larger with AVERROR_INVALIDDATA.

Verified end-to-end with the audit PoC: 100 MiB and 10 MiB Content-Length
values are now rejected at header-parse time ("Invalid Content-Length ...
in ANNOUNCE"), while a legitimate 112-byte SDP body is still accepted and
parsed normally. No regressions in the valid-SDP scenario.

Reported by Franciszek Kalinowski (isec.pl / striga.ai) and Bartosz Smigielski.


>From 33d48b2bf33e243c53af02d4a309c73deba8d798 Mon Sep 17 00:00:00 2001
From: Franciszek Kalinowski <[email protected]>
Date: Tue, 19 May 2026 09:40:41 +0200
Subject: [PATCH] avformat/rtspdec: bound Content-Length in the ANNOUNCE
 handler

rtsp_read_announce() reads Content-Length from the RTSP request and passes
it directly to av_malloc() without any upper-bound check. An attacker who
can talk to an RTSP listener (`ffmpeg -rtsp_flags listen ...`) can request
an arbitrary allocation size with a single ANNOUNCE header. Repeating it
exhausts memory, and Content-Length: INT_MAX overflows content_length+1
to 0 and turns into an undersized buffer + large read.

Cap content_length at 64 KiB (more than any realistic SDP) before the
av_malloc() and reject anything larger with AVERROR_INVALIDDATA.

Verified end-to-end with the audit PoC: 100 MiB and 10 MiB Content-Length
values are now rejected at header-parse time ("Invalid Content-Length ...
in ANNOUNCE"), while a legitimate 112-byte SDP body is still accepted and
parsed normally. No regressions in the valid-SDP scenario.

Reported by Franciszek Kalinowski (isec.pl / striga.ai) and Bartosz Smigielski.
---
 libavformat/rtspdec.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index e0bdf9d4ac..8d3871f263 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -181,6 +181,8 @@ static int rtsp_read_announce(AVFormatContext *s)
     char *sdp;
     int  ret;
 
+#define RTSP_MAX_CONTENT_LENGTH (1 * 1024 * 1024)
+
     ret = rtsp_read_request(s, &request, "ANNOUNCE");
     if (ret)
         return ret;
@@ -191,6 +193,13 @@ static int rtsp_read_announce(AVFormatContext *s)
         rtsp_send_reply(s, RTSP_STATUS_SERVICE, NULL, request.seq);
         return AVERROR_OPTION_NOT_FOUND;
     }
+    if (request.content_length < 0 ||
+        request.content_length > RTSP_MAX_CONTENT_LENGTH) {
+        av_log(s, AV_LOG_ERROR, "Invalid Content-Length %d in ANNOUNCE\n",
+               request.content_length);
+        rtsp_send_reply(s, RTSP_STATUS_INTERNAL, NULL, request.seq);
+        return AVERROR_INVALIDDATA;
+    }
     if (request.content_length > 0) {
         sdp = av_malloc(request.content_length + 1);
         if (!sdp)
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to