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] avformat/mpegenc: Fix ever growing FIFO and infinite loop on error
@ 2022-04-01  9:23 Andreas Rheinhardt
  2022-04-05 14:30 ` Andreas Rheinhardt
  0 siblings, 1 reply; 2+ messages in thread
From: Andreas Rheinhardt @ 2022-04-01  9:23 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Nicolas Gaullier, Andreas Rheinhardt

Since the switch to the new FIFO API in commit
ea511196a6c85eb433e10cdbecb0b2c722faf20d, the FIFO is always
grown by the amount of data intended to be written into it
even in case the FIFO has enough free space. Fix this by
only growing the FIFO if needed and then only by the amount that is
actually needed.

The allocation errors that resulted from this uncovered another bug:
The context is left in an inconsistent state in case the FIFO can't
be grown, because the FIFO does not contain as much data as the sizes
contained in the PacketDesc list claim. This led to an infinite loop
in output_packet() (called from mpeg_mux_end()).

Fix this by growing the FIFO before adding a new PacketDesc element,
thereby preventing the context from becoming inconsistent.

Reported-by: Nicolas Gaullier <nicolas.gaullier@cji.paris>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
 libavformat/mpegenc.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c
index cc47a43288..62692bfcd1 100644
--- a/libavformat/mpegenc.c
+++ b/libavformat/mpegenc.c
@@ -1152,6 +1152,7 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
     int64_t pts, dts;
     PacketDesc *pkt_desc;
     int preload, ret;
+    size_t can_write;
     const int is_iframe = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
                           (pkt->flags & AV_PKT_FLAG_KEY);
 
@@ -1192,6 +1193,14 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
         size -= 3;
     }
 
+    /* Enlarge the FIFO before adding a new PacketDesc
+     * in order to avoid inconsistencies on failure. */
+    can_write = av_fifo_can_write(stream->fifo);
+    if (can_write < size) {
+        ret = av_fifo_grow2(stream->fifo, size - can_write);
+        if (ret < 0)
+            return ret;
+    }
     pkt_desc                 = av_mallocz(sizeof(PacketDesc));
     if (!pkt_desc)
         return AVERROR(ENOMEM);
@@ -1207,10 +1216,6 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
     pkt_desc->unwritten_size =
     pkt_desc->size           = size;
 
-    ret = av_fifo_grow2(stream->fifo, size);
-    if (ret < 0)
-        return ret;
-
     if (s->is_dvd) {
         // min VOBU length 0.4 seconds (mpucoder)
         if (is_iframe &&
-- 
2.32.0

_______________________________________________
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] 2+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avformat/mpegenc: Fix ever growing FIFO and infinite loop on error
  2022-04-01  9:23 [FFmpeg-devel] [PATCH] avformat/mpegenc: Fix ever growing FIFO and infinite loop on error Andreas Rheinhardt
@ 2022-04-05 14:30 ` Andreas Rheinhardt
  0 siblings, 0 replies; 2+ messages in thread
From: Andreas Rheinhardt @ 2022-04-05 14:30 UTC (permalink / raw)
  To: ffmpeg-devep, ffmpeg-devel; +Cc: Nicolas Gaullier

Andreas Rheinhardt:
> Since the switch to the new FIFO API in commit
> ea511196a6c85eb433e10cdbecb0b2c722faf20d, the FIFO is always
> grown by the amount of data intended to be written into it
> even in case the FIFO has enough free space. Fix this by
> only growing the FIFO if needed and then only by the amount that is
> actually needed.
> 
> The allocation errors that resulted from this uncovered another bug:
> The context is left in an inconsistent state in case the FIFO can't
> be grown, because the FIFO does not contain as much data as the sizes
> contained in the PacketDesc list claim. This led to an infinite loop
> in output_packet() (called from mpeg_mux_end()).
> 
> Fix this by growing the FIFO before adding a new PacketDesc element,
> thereby preventing the context from becoming inconsistent.
> 
> Reported-by: Nicolas Gaullier <nicolas.gaullier@cji.paris>
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
> ---
>  libavformat/mpegenc.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c
> index cc47a43288..62692bfcd1 100644
> --- a/libavformat/mpegenc.c
> +++ b/libavformat/mpegenc.c
> @@ -1152,6 +1152,7 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
>      int64_t pts, dts;
>      PacketDesc *pkt_desc;
>      int preload, ret;
> +    size_t can_write;
>      const int is_iframe = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
>                            (pkt->flags & AV_PKT_FLAG_KEY);
>  
> @@ -1192,6 +1193,14 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
>          size -= 3;
>      }
>  
> +    /* Enlarge the FIFO before adding a new PacketDesc
> +     * in order to avoid inconsistencies on failure. */
> +    can_write = av_fifo_can_write(stream->fifo);
> +    if (can_write < size) {
> +        ret = av_fifo_grow2(stream->fifo, size - can_write);
> +        if (ret < 0)
> +            return ret;
> +    }
>      pkt_desc                 = av_mallocz(sizeof(PacketDesc));
>      if (!pkt_desc)
>          return AVERROR(ENOMEM);
> @@ -1207,10 +1216,6 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
>      pkt_desc->unwritten_size =
>      pkt_desc->size           = size;
>  
> -    ret = av_fifo_grow2(stream->fifo, size);
> -    if (ret < 0)
> -        return ret;
> -
>      if (s->is_dvd) {
>          // min VOBU length 0.4 seconds (mpucoder)
>          if (is_iframe &&

Will apply this tonight unless there are objections.

- Andreas
_______________________________________________
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] 2+ messages in thread

end of thread, other threads:[~2022-04-05 14:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-01  9:23 [FFmpeg-devel] [PATCH] avformat/mpegenc: Fix ever growing FIFO and infinite loop on error Andreas Rheinhardt
2022-04-05 14:30 ` Andreas Rheinhardt

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