From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> To: ffmpeg-devel@ffmpeg.org Cc: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> Subject: [FFmpeg-devel] [PATCH 1/3] avformat/rcwtenc: Fix potential out-of-bounds write Date: Thu, 8 Feb 2024 16:08:45 +0100 Message-ID: <AS8P250MB0744DEA814843EE4DB353AAD8F442@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM> (raw) The rcwt muxer uses several counters for how much data it has already cached: One byte counter and one counter for how many complete blocks (of three bytes each). These counters can become inconsistent when the muxer is fed incomplete blocks as the muxer presumes that it is about to write a new block at the start of each write_packet call. E.g. sending 65535*3+1 1-byte packets (with data[0] e.g. 0x03) will trigger an out-of-bounds write. This patch fixes this by processing the data in complete blocks only. This also allows to simplify the code, e.g. to remove one of the counters. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavformat/rcwtenc.c | 38 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/libavformat/rcwtenc.c b/libavformat/rcwtenc.c index 839436ce84..d0e469ce65 100644 --- a/libavformat/rcwtenc.c +++ b/libavformat/rcwtenc.c @@ -65,7 +65,6 @@ #define RCWT_BLOCK_SIZE 3 typedef struct RCWTContext { - int cluster_nb_blocks; int cluster_pos; int64_t cluster_pts; uint8_t cluster_buf[RCWT_CLUSTER_MAX_BLOCKS * RCWT_BLOCK_SIZE]; @@ -75,7 +74,6 @@ static void rcwt_init_cluster(AVFormatContext *avf) { RCWTContext *rcwt = avf->priv_data; - rcwt->cluster_nb_blocks = 0; rcwt->cluster_pos = 0; rcwt->cluster_pts = AV_NOPTS_VALUE; memset(rcwt->cluster_buf, 0, sizeof(rcwt->cluster_buf)); @@ -85,10 +83,10 @@ static void rcwt_flush_cluster(AVFormatContext *avf) { RCWTContext *rcwt = avf->priv_data; - if (rcwt->cluster_nb_blocks > 0) { + if (rcwt->cluster_pos > 0) { avio_wl64(avf->pb, rcwt->cluster_pts); - avio_wl16(avf->pb, rcwt->cluster_nb_blocks); - avio_write(avf->pb, rcwt->cluster_buf, (rcwt->cluster_nb_blocks * RCWT_BLOCK_SIZE)); + avio_wl16(avf->pb, rcwt->cluster_pos / 3); + avio_write(avf->pb, rcwt->cluster_buf, rcwt->cluster_pos); } rcwt_init_cluster(avf); @@ -129,10 +127,7 @@ static int rcwt_write_packet(AVFormatContext *avf, AVPacket *pkt) { RCWTContext *rcwt = avf->priv_data; - int in_block = 0; - int nb_block_bytes = 0; - - if (pkt->size == 0) + if (pkt->size <= 2) return 0; /* new PTS, new cluster */ @@ -146,11 +141,11 @@ static int rcwt_write_packet(AVFormatContext *avf, AVPacket *pkt) return 0; } - for (int i = 0; i < pkt->size; i++) { + for (int i = 0; i < pkt->size - 2;) { uint8_t cc_valid; uint8_t cc_type; - if (rcwt->cluster_nb_blocks == RCWT_CLUSTER_MAX_BLOCKS) { + if (rcwt->cluster_pos == RCWT_CLUSTER_MAX_BLOCKS * RCWT_BLOCK_SIZE) { av_log(avf, AV_LOG_WARNING, "Starting new cluster due to size\n"); rcwt_flush_cluster(avf); } @@ -158,25 +153,14 @@ static int rcwt_write_packet(AVFormatContext *avf, AVPacket *pkt) cc_valid = (pkt->data[i] & 0x04) >> 2; cc_type = pkt->data[i] & 0x03; - if (!in_block && !(cc_valid || cc_type == 3)) - continue; - - memcpy(&rcwt->cluster_buf[rcwt->cluster_pos], &pkt->data[i], 1); - rcwt->cluster_pos++; - - if (!in_block) { - in_block = 1; - nb_block_bytes = 1; + if (!(cc_valid || cc_type == 3)) { + i++; continue; } - nb_block_bytes++; - - if (nb_block_bytes == RCWT_BLOCK_SIZE) { - in_block = 0; - nb_block_bytes = 0; - rcwt->cluster_nb_blocks++; - } + memcpy(&rcwt->cluster_buf[rcwt->cluster_pos], &pkt->data[i], 3); + rcwt->cluster_pos += 3; + i += 3; } return 0; -- 2.34.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next reply other threads:[~2024-02-08 15:07 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top 2024-02-08 15:08 Andreas Rheinhardt [this message] 2024-02-08 15:09 ` [FFmpeg-devel] [PATCH 2/3] avformat/rcwtenc: Remove redundant zeroing of buffer Andreas Rheinhardt 2024-02-08 15:09 ` [FFmpeg-devel] [PATCH 3/3] avformat/rcwtenc: Pass RCWTContext directly in rcwt_init_cluster() Andreas Rheinhardt 2024-02-09 7:34 ` Marth64
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=AS8P250MB0744DEA814843EE4DB353AAD8F442@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM \ --to=andreas.rheinhardt@outlook.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git