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

send_packet() copied an input-derived unit/fragment size into the fixed
rtp_ctx->buf with no bound, overflowing it for a crafted Dirac unit even at
the default packet size. Reject units that do not fit in max_payload_size.

Fixes: out of array access



>From 3ac4250ce720ab84b5c5e4127d211cb4628f8831 Mon Sep 17 00:00:00 2001
From: Joshua Rogers <[email protected]>
Date: Tue, 4 Aug 2026 12:11:55 +0000
Subject: [PATCH] avformat/rtpenc_vc2hq: reject data units larger than the RTP
 payload buffer

send_packet() copied an input-derived unit/fragment size into the fixed
rtp_ctx->buf with no bound, overflowing it for a crafted Dirac unit even at
the default packet size. Reject units that do not fit in max_payload_size.

Fixes: out of array access
---
 libavformat/rtpenc_vc2hq.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/libavformat/rtpenc_vc2hq.c b/libavformat/rtpenc_vc2hq.c
index cf548191d2..3b7147dfe2 100644
--- a/libavformat/rtpenc_vc2hq.c
+++ b/libavformat/rtpenc_vc2hq.c
@@ -33,16 +33,23 @@
 #define DIRAC_PIC_NR_SIZE                    4
 #define DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT      0xEC
 
-static void send_packet(AVFormatContext *ctx, uint8_t parse_code, int 
info_hdr_size, const uint8_t *buf, int size, int i, int f, int rtp_m)
+static int send_packet(AVFormatContext *ctx, uint8_t parse_code, int 
info_hdr_size, const uint8_t *buf, int size, int i, int f, int rtp_m)
 {
     RTPMuxContext *rtp_ctx = ctx->priv_data;
 
+    if (size < 0 ||
+        size > rtp_ctx->max_payload_size - RTP_VC2HQ_PL_HEADER_SIZE - 
info_hdr_size) {
+        av_log(ctx, AV_LOG_ERROR, "VC-2 data unit too large for RTP payload 
buffer\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     AV_WB16(&rtp_ctx->buf[0], 0); /* extended sequence number */
     AV_WB8 (&rtp_ctx->buf[2], i ? (f ? (0x03) : (0x02)) : 0x00); /* flags: 
interlaced, second field */
     AV_WB8 (&rtp_ctx->buf[3], parse_code);
     if (size > 0)
         memcpy(&rtp_ctx->buf[4 + info_hdr_size], buf, size);
     ff_rtp_send_data(ctx, rtp_ctx->buf, RTP_VC2HQ_PL_HEADER_SIZE + 
info_hdr_size + size, rtp_m);
+    return 0;
 }
 
 static int send_picture(AVFormatContext *ctx, const uint8_t *buf, int size, 
int interlaced)
@@ -85,7 +92,8 @@ static int send_picture(AVFormatContext *ctx, const uint8_t 
*buf, int size, int
     AV_WB16(&info_hdr[ 6], size_scaler);
     AV_WB16(&info_hdr[ 8], frag_len);
     AV_WB16(&info_hdr[10], 0 /* nr. of slices */);
-    send_packet(ctx, DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT, 12, buf, frag_len, 
interlaced, second_field, 0);
+    if (send_packet(ctx, DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT, 12, buf, frag_len, 
interlaced, second_field, 0) < 0)
+        return AVERROR_INVALIDDATA;
     buf += frag_len;
     size -= frag_len;
 
@@ -97,7 +105,8 @@ static int send_picture(AVFormatContext *ctx, const uint8_t 
*buf, int size, int
         AV_WB16(&info_hdr[14], 0 /* slice y */);
 
         size -= frag_len;
-        send_packet(ctx, DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT, 16, buf, frag_len, 
interlaced, second_field, size > 0 ? 0 : 1);
+        if (send_packet(ctx, DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT, 16, buf, 
frag_len, interlaced, second_field, size > 0 ? 0 : 1) < 0)
+            return AVERROR_INVALIDDATA;
         buf += frag_len;
     }
     return 0;
-- 
2.52.0

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

Reply via email to