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]