PR #25222 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25222 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25222.patch
Found during triage of the security report TwYfznAFyatl Found-by: zhang xingxing >From 44d6da9bdb8a148980bb8bac72887b007f1ae8c9 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 19 Oct 2026 02:13:33 +0200 Subject: [PATCH 01/11] avformat/rtpenc: Reject packet sizes too small for the payload header Fixes: negative-size-param Fixes: infinite loop Fixes: TwYfznAFyatl Fixes: #22717 Fixes: ffmpeg -f lavfi -i testsrc=duration=0.1:size=16x16:rate=1 -c:v libvpx -f rtp -packetsize 13 rtp://127.0.0.1:9999 Negative-size memcpy and endless loop Replicated through UnModified FFmpeg with ASAN Found-by: bird <[email protected]> --- libavformat/rtpenc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 7f09329b10..24bf6b93f8 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -101,6 +101,7 @@ static int rtp_write_header(AVFormatContext *s1) { RTPMuxContext *s = s1->priv_data; int n, ret = AVERROR(EINVAL); + int payload_header_size = 0; AVStream *st; if (s1->nb_streams != 1) { @@ -212,12 +213,14 @@ static int rtp_write_header(AVFormatContext *s1) ret = AVERROR_EXPERIMENTAL; goto fail; } + payload_header_size = 4; break; case AV_CODEC_ID_H264: /* check for H.264 MP4 syntax */ if (st->codecpar->extradata_size > 4 && st->codecpar->extradata[0] == 1) { s->nal_length_size = (st->codecpar->extradata[4] & 0x03) + 1; } + payload_header_size = 2; break; case AV_CODEC_ID_HEVC: /* Only check for the standardized hvcC version of extradata, keeping @@ -227,6 +230,10 @@ static int rtp_write_header(AVFormatContext *s1) if (st->codecpar->extradata_size > 21 && st->codecpar->extradata[0] == 1) { s->nal_length_size = (st->codecpar->extradata[21] & 0x03) + 1; } + payload_header_size = 3; + break; + case AV_CODEC_ID_VP8: + payload_header_size = 4; break; case AV_CODEC_ID_BITPACKED: case AV_CODEC_ID_RAWVIDEO: @@ -307,11 +314,19 @@ static int rtp_write_header(AVFormatContext *s1) break; case AV_CODEC_ID_AAC: s->max_frames_per_packet = 50; + if (!(s->flags & FF_RTP_FLAG_MP4A_LATM)) + payload_header_size = 4; break; default: break; } + if (s->max_payload_size <= payload_header_size) { + av_log(s1, AV_LOG_ERROR, "Max packet size %u too low for a %d byte payload header\n", + s1->packet_size, payload_header_size); + goto fail; + } + return 0; fail: -- 2.54.0 >From c7091da9a286b57fc87fa5a557fe6251358f57b5 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 19 Oct 2026 02:14:25 +0200 Subject: [PATCH 02/11] avformat/rtpenc: Reject packet sizes too small for the MPEG video payload header Fixes: negative-size-param Fixes: infinite loop Fixes: vrmb3QRC6jK1 Fixes: swarm-Signed-integer-underflow-in-RTP-MPEG-video-packet-length-4acadd Fixes: ffmpeg -f lavfi -i color=size=64x64:duration=1 -packetsize 13 -c:v mpeg1video -f rtp rtp://127.0.0.1:45004 Negative-size memcpy and endless loop Replicated through UnModified FFmpeg with ASAN Found-by: zhang xingxing <[email protected]> --- libavformat/rtpenc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 24bf6b93f8..471c988d9c 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -178,6 +178,7 @@ static int rtp_write_header(AVFormatContext *s1) break; case AV_CODEC_ID_MPEG1VIDEO: case AV_CODEC_ID_MPEG2VIDEO: + payload_header_size = 4; break; case AV_CODEC_ID_MPEG2TS: if (s->max_payload_size < TS_PACKET_SIZE) { -- 2.54.0 >From ea34662895f67ce4fcef919ed3f24f9ee87dbe1f Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 19 Oct 2026 02:14:42 +0200 Subject: [PATCH 03/11] avformat/rtpenc: Reject packet sizes too small for the MPEG audio payload header Fixes: negative-size-param Fixes: infinite loop Fixes: KX3pF2MSORSh Fixes: ffmpeg -f lavfi -i sine=d=0.2 -c:a mp2 -f rtp -packetsize 13 /dev/null Negative-size memcpy and endless loop Replicated through UnModified FFmpeg with ASAN Found during triage of the security report TwYfznAFyatl (#22717) --- libavformat/rtpenc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 471c988d9c..dff76aab44 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -174,6 +174,7 @@ static int rtp_write_header(AVFormatContext *s1) case AV_CODEC_ID_MP2: case AV_CODEC_ID_MP3: s->buf_ptr = s->buf + 4; + payload_header_size = 4; avpriv_set_pts_info(st, 32, 1, 90000); break; case AV_CODEC_ID_MPEG1VIDEO: -- 2.54.0 >From c5105ba9d07a6a25dc86743599d60613eafca873 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 19 Oct 2026 02:15:12 +0200 Subject: [PATCH 04/11] avformat/rtpenc: Reject packet sizes too small for the H.263 payload header Fixes: negative-size-param Fixes: infinite loop Fixes: gFLqHoPMr8J5 Fixes: ffmpeg -f lavfi -i testsrc=duration=0.2:size=176x144:rate=5 -c:v h263 -f rtp -packetsize 13 /dev/null Fixes: ffmpeg -f lavfi -i testsrc=duration=0.2:size=176x144:rate=5 -c:v h263 -rtpflags rfc2190 -f rtp -packetsize 13 /dev/null Negative-size memcpy and endless loop Replicated through UnModified FFmpeg with ASAN Found during triage of the security report TwYfznAFyatl (#22717) --- libavformat/rtpenc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index dff76aab44..26f89cd7af 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -205,6 +205,15 @@ static int rtp_write_header(AVFormatContext *s1) goto fail; } break; + case AV_CODEC_ID_H263: + if (s->flags & FF_RTP_FLAG_RFC2190) { + payload_header_size = 8; + break; + } + av_fallthrough; + case AV_CODEC_ID_H263P: + payload_header_size = 2; + break; case AV_CODEC_ID_H261: if (s1->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { av_log(s, AV_LOG_ERROR, -- 2.54.0 >From 2c4205855bfc7ccd7446acec1798a0b1961f721e Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 19 Oct 2026 02:15:19 +0200 Subject: [PATCH 05/11] avformat/rtpenc: Reject packet sizes too small for the VP9 payload descriptor Fixes: infinite loop Fixes: 2bIuZUVk7KRO Fixes: ffmpeg -f lavfi -i testsrc=duration=0.2:size=64x64:rate=5 -c:v libvpx-vp9 -strict experimental -f rtp -packetsize 13 /dev/null Endless loop Replicated through UnModified FFmpeg Found during triage of the security report TwYfznAFyatl (#22717) --- libavformat/rtpenc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 26f89cd7af..d2a8646a95 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -269,6 +269,7 @@ static int rtp_write_header(AVFormatContext *s1) ret = AVERROR_EXPERIMENTAL; goto fail; } + payload_header_size = 1; break; case AV_CODEC_ID_AV1: if (s1->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { -- 2.54.0 >From 3a3ae59100b980f2a1a2c0ab0715385ad92da9fe Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 19 Oct 2026 02:15:27 +0200 Subject: [PATCH 06/11] avformat/rtpenc: Reject packet sizes too small for the AV1 payload headers Fixes: heap-buffer-overflow Fixes: FyS11JI5UXC7 Fixes: ffmpeg -i fate-suite/av1/film_grain.ivf -frames:v 2 -c copy -strict experimental -f rtp -packetsize 13 /dev/null Out of array read Replicated through UnModified FFmpeg with ASAN Found during triage of the security report TwYfznAFyatl (#22717) --- libavformat/rtpenc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index d2a8646a95..b3a5b0ff35 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -280,6 +280,7 @@ static int rtp_write_header(AVFormatContext *s1) ret = AVERROR_EXPERIMENTAL; goto fail; } + payload_header_size = 3; break; case AV_CODEC_ID_VORBIS: case AV_CODEC_ID_THEORA: -- 2.54.0 >From f0f07b9a4887c0d46269243fad1f222288aa6047 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 19 Oct 2026 02:15:40 +0200 Subject: [PATCH 07/11] avformat/rtpenc: Reject packet sizes too small for the VC-2 payload header Fixes: heap-buffer-overflow Fixes: zZoxZuoiTRhn Out of array write Replicated through UnModified FFmpeg with ASAN Found during triage of the security report TwYfznAFyatl (#22717) --- libavformat/rtpenc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index b3a5b0ff35..8f14fee073 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -204,6 +204,7 @@ static int rtp_write_header(AVFormatContext *s1) ret = AVERROR_EXPERIMENTAL; goto fail; } + payload_header_size = 20; break; case AV_CODEC_ID_H263: if (s->flags & FF_RTP_FLAG_RFC2190) { -- 2.54.0 >From c20fd1d99e4482947525bf63d5b72f8a41c9b322 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 19 Oct 2026 02:15:48 +0200 Subject: [PATCH 08/11] avformat/rtpenc: Reject packet sizes too small for one iLBC frame Fixes: heap-buffer-overflow Fixes: sbHrRrZhcbbZ Out of array write Replicated through UnModified FFmpeg with ASAN Found during triage of the security report TwYfznAFyatl (#22717) --- libavformat/rtpenc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 8f14fee073..1c91e32fbe 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -308,6 +308,10 @@ static int rtp_write_header(AVFormatContext *s1) goto fail; } s->max_frames_per_packet = s->max_payload_size / st->codecpar->block_align; + if (!s->max_frames_per_packet) { + av_log(s1, AV_LOG_ERROR, "RTP max payload size too small for iLBC\n"); + goto fail; + } break; case AV_CODEC_ID_AMR_NB: case AV_CODEC_ID_AMR_WB: -- 2.54.0 >From 38d265cf10458a0a6287c15028c720c78bfbe78c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 19 Oct 2026 02:15:57 +0200 Subject: [PATCH 09/11] avformat/rtpenc: Reject packet sizes too small for one sample Fixes: infinite loop Fixes: bz6tTr9RAaZT Fixes: ffmpeg -f lavfi -i sine=d=0.2 -c:a pcm_s16be -f rtp -packetsize 13 /dev/null Fixes: ffmpeg -f lavfi -i sine=d=0.2 -ar 8000 -c:a g726 -b:a 24k -f rtp -packetsize 14 /dev/null Endless loop Replicated through UnModified FFmpeg Found during triage of the security report TwYfznAFyatl (#22717) --- libavformat/rtpenc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 1c91e32fbe..b42a0f2d4b 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -434,6 +434,11 @@ static int rtp_send_samples(AVFormatContext *s1, int aligned_samples_size = sample_size_bits/av_gcd(sample_size_bits, 8); max_packet_size = (s->max_payload_size / aligned_samples_size) * aligned_samples_size; + if (!max_packet_size) { + av_log(s1, AV_LOG_ERROR, "RTP max payload size too small for %d byte samples\n", + aligned_samples_size); + return AVERROR(EINVAL); + } /* Not needed, but who knows. Don't check if samples aren't an even number of bytes. */ if ((sample_size_bits % 8) == 0 && ((8 * size) % sample_size_bits) != 0) return AVERROR(EINVAL); -- 2.54.0 >From 20b407790c559f15fa706429bda9ba26a97589da Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 19 Oct 2026 02:16:05 +0200 Subject: [PATCH 10/11] avformat/rtpenc_jpeg: Check that the JPEG payload header fits in the packet Fixes: heap-buffer-overflow Fixes: negative-size-param Fixes: infinite loop Fixes: hnrHe6JoiDya Out of array write, negative-size memcpy and endless loop Replicated through UnModified FFmpeg with ASAN Found during triage of the security report TwYfznAFyatl (#22717), the JPEG case is mentioned in the discussion of the issue --- libavformat/rtpenc_jpeg.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavformat/rtpenc_jpeg.c b/libavformat/rtpenc_jpeg.c index ddbce261d4..ffffb7cd15 100644 --- a/libavformat/rtpenc_jpeg.c +++ b/libavformat/rtpenc_jpeg.c @@ -208,6 +208,12 @@ void ff_rtp_send_jpeg(AVFormatContext *s1, const uint8_t *buf, int size) if (off == 0 && nb_qtables) hdr_size += 4 + 64 * nb_qtables; + if (hdr_size >= s->max_payload_size) { + av_log(s1, AV_LOG_ERROR, "RTP max payload size %d too small for the %d byte JPEG header\n", + s->max_payload_size, hdr_size); + return; + } + /* payload max in one packet */ len = FFMIN(size, s->max_payload_size - hdr_size); -- 2.54.0 >From 2e35f8da53c1895f58f69520e0722a843aee36e4 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 19 Oct 2026 02:23:09 +0200 Subject: [PATCH 11/11] avformat/rtpenc: Fragment MPEG audio frames that do not fit with the payload header Fixes: ffmpeg -f lavfi -i sine=d=0.5 -ar 48000 -c:a mp2 -b:a 128k -f rtp -packetsize 396 rtp://127.0.0.1:45111?pkt_size=396 Found during triage of the security report TwYfznAFyatl (#22717) --- libavformat/rtpenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index b42a0f2d4b..823e5e2cf2 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -480,7 +480,7 @@ static void rtp_send_mpegaudio(AVFormatContext *s1, } /* add the packet */ - if (size > max_packet_size) { + if (size > max_packet_size - 4) { /* big packet: fragment */ count = 0; while (size > 0) { -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
