Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH 1/3] avformat/rcwtenc: Fix potential out-of-bounds write
@ 2024-02-08 15:08 Andreas Rheinhardt
  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
  0 siblings, 2 replies; 4+ messages in thread
From: Andreas Rheinhardt @ 2024-02-08 15:08 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andreas Rheinhardt

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".

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [FFmpeg-devel] [PATCH 2/3] avformat/rcwtenc: Remove redundant zeroing of buffer
  2024-02-08 15:08 [FFmpeg-devel] [PATCH 1/3] avformat/rcwtenc: Fix potential out-of-bounds write Andreas Rheinhardt
@ 2024-02-08 15:09 ` Andreas Rheinhardt
  2024-02-08 15:09 ` [FFmpeg-devel] [PATCH 3/3] avformat/rcwtenc: Pass RCWTContext directly in rcwt_init_cluster() Andreas Rheinhardt
  1 sibling, 0 replies; 4+ messages in thread
From: Andreas Rheinhardt @ 2024-02-08 15:09 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andreas Rheinhardt

Resetting the counter of used elements is enough as nothing is
ever read from the currently unused elements.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavformat/rcwtenc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libavformat/rcwtenc.c b/libavformat/rcwtenc.c
index d0e469ce65..084de6e205 100644
--- a/libavformat/rcwtenc.c
+++ b/libavformat/rcwtenc.c
@@ -76,7 +76,6 @@ static void rcwt_init_cluster(AVFormatContext *avf)
 
     rcwt->cluster_pos = 0;
     rcwt->cluster_pts = AV_NOPTS_VALUE;
-    memset(rcwt->cluster_buf, 0, sizeof(rcwt->cluster_buf));
 }
 
 static void rcwt_flush_cluster(AVFormatContext *avf)
-- 
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".

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [FFmpeg-devel] [PATCH 3/3] avformat/rcwtenc: Pass RCWTContext directly in rcwt_init_cluster()
  2024-02-08 15:08 [FFmpeg-devel] [PATCH 1/3] avformat/rcwtenc: Fix potential out-of-bounds write Andreas Rheinhardt
  2024-02-08 15:09 ` [FFmpeg-devel] [PATCH 2/3] avformat/rcwtenc: Remove redundant zeroing of buffer Andreas Rheinhardt
@ 2024-02-08 15:09 ` Andreas Rheinhardt
  2024-02-09  7:34   ` Marth64
  1 sibling, 1 reply; 4+ messages in thread
From: Andreas Rheinhardt @ 2024-02-08 15:09 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andreas Rheinhardt

It does not use the AVFormatContext at all.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavformat/rcwtenc.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/libavformat/rcwtenc.c b/libavformat/rcwtenc.c
index 084de6e205..7d57fcaf1e 100644
--- a/libavformat/rcwtenc.c
+++ b/libavformat/rcwtenc.c
@@ -70,10 +70,8 @@ typedef struct RCWTContext {
     uint8_t cluster_buf[RCWT_CLUSTER_MAX_BLOCKS * RCWT_BLOCK_SIZE];
 } RCWTContext;
 
-static void rcwt_init_cluster(AVFormatContext *avf)
+static void rcwt_init_cluster(RCWTContext *rcwt)
 {
-    RCWTContext *rcwt = avf->priv_data;
-
     rcwt->cluster_pos = 0;
     rcwt->cluster_pts = AV_NOPTS_VALUE;
 }
@@ -88,7 +86,7 @@ static void rcwt_flush_cluster(AVFormatContext *avf)
         avio_write(avf->pb, rcwt->cluster_buf, rcwt->cluster_pos);
     }
 
-    rcwt_init_cluster(avf);
+    rcwt_init_cluster(rcwt);
 }
 
 static int rcwt_write_header(AVFormatContext *avf)
@@ -117,7 +115,7 @@ static int rcwt_write_header(AVFormatContext *avf)
     avio_wb16(avf->pb, 0x000);
     avio_w8(avf->pb, 0x00);
 
-    rcwt_init_cluster(avf);
+    rcwt_init_cluster(avf->priv_data);
 
     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".

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [FFmpeg-devel] [PATCH 3/3] avformat/rcwtenc: Pass RCWTContext directly in rcwt_init_cluster()
  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
  0 siblings, 0 replies; 4+ messages in thread
From: Marth64 @ 2024-02-09  7:34 UTC (permalink / raw)
  To: FFmpeg development discussions and patches; +Cc: Andreas Rheinhardt

v2 set LGTM. I verified with ATSC and DVD sources. Thank you.

On Thu, Feb 8, 2024 at 9:08 AM Andreas Rheinhardt <
andreas.rheinhardt@outlook.com> wrote:

> It does not use the AVFormatContext at all.
>
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
> ---
>  libavformat/rcwtenc.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/libavformat/rcwtenc.c b/libavformat/rcwtenc.c
> index 084de6e205..7d57fcaf1e 100644
> --- a/libavformat/rcwtenc.c
> +++ b/libavformat/rcwtenc.c
> @@ -70,10 +70,8 @@ typedef struct RCWTContext {
>      uint8_t cluster_buf[RCWT_CLUSTER_MAX_BLOCKS * RCWT_BLOCK_SIZE];
>  } RCWTContext;
>
> -static void rcwt_init_cluster(AVFormatContext *avf)
> +static void rcwt_init_cluster(RCWTContext *rcwt)
>  {
> -    RCWTContext *rcwt = avf->priv_data;
> -
>      rcwt->cluster_pos = 0;
>      rcwt->cluster_pts = AV_NOPTS_VALUE;
>  }
> @@ -88,7 +86,7 @@ static void rcwt_flush_cluster(AVFormatContext *avf)
>          avio_write(avf->pb, rcwt->cluster_buf, rcwt->cluster_pos);
>      }
>
> -    rcwt_init_cluster(avf);
> +    rcwt_init_cluster(rcwt);
>  }
>
>  static int rcwt_write_header(AVFormatContext *avf)
> @@ -117,7 +115,7 @@ static int rcwt_write_header(AVFormatContext *avf)
>      avio_wb16(avf->pb, 0x000);
>      avio_w8(avf->pb, 0x00);
>
> -    rcwt_init_cluster(avf);
> +    rcwt_init_cluster(avf->priv_data);
>
>      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".
>
_______________________________________________
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".

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-02-09  7:35 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-08 15:08 [FFmpeg-devel] [PATCH 1/3] avformat/rcwtenc: Fix potential out-of-bounds write Andreas Rheinhardt
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

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