[FFmpeg-cvslog] avcodec/bsf: Fix segfault when freeing half-allocated BSF

Andreas Rheinhardt git at videolan.org
Sat Apr 3 01:19:09 EEST 2021


ffmpeg | branch: release/4.4 | Andreas Rheinhardt <andreas.rheinhardt at outlook.com> | Fri Apr  2 14:17:56 2021 +0200| [60433ae94fc53cb694150ad79263e2074b6a56ef] | committer: Andreas Rheinhardt

avcodec/bsf: Fix segfault when freeing half-allocated BSF

When allocating a BSF fails, it could happen that the BSF's close
function has been called despite a failure to allocate the private data.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
(cherry picked from commit 9bf2b32da048732ad79e075dfefd40777e9f935a)

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=60433ae94fc53cb694150ad79263e2074b6a56ef
---

 libavcodec/bsf.c | 39 ++++++++++++++++++++-------------------
 1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/libavcodec/bsf.c b/libavcodec/bsf.c
index d71bc32584..157984bd9a 100644
--- a/libavcodec/bsf.c
+++ b/libavcodec/bsf.c
@@ -45,14 +45,15 @@ void av_bsf_free(AVBSFContext **pctx)
         return;
     ctx = *pctx;
 
-    if (ctx->filter->close)
-        ctx->filter->close(ctx);
+    if (ctx->internal) {
+        if (ctx->filter->close)
+            ctx->filter->close(ctx);
+        av_packet_free(&ctx->internal->buffer_pkt);
+        av_freep(&ctx->internal);
+    }
     if (ctx->filter->priv_class && ctx->priv_data)
         av_opt_free(ctx->priv_data);
 
-    if (ctx->internal)
-        av_packet_free(&ctx->internal->buffer_pkt);
-    av_freep(&ctx->internal);
     av_freep(&ctx->priv_data);
 
     avcodec_parameters_free(&ctx->par_in);
@@ -110,20 +111,6 @@ int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx)
         ret = AVERROR(ENOMEM);
         goto fail;
     }
-
-    bsfi = av_mallocz(sizeof(*bsfi));
-    if (!bsfi) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
-    ctx->internal = bsfi;
-
-    bsfi->buffer_pkt = av_packet_alloc();
-    if (!bsfi->buffer_pkt) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
-
     /* allocate priv data and init private options */
     if (filter->priv_data_size) {
         ctx->priv_data = av_mallocz(filter->priv_data_size);
@@ -136,6 +123,20 @@ int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx)
             av_opt_set_defaults(ctx->priv_data);
         }
     }
+    /* Allocate AVBSFInternal; must happen after priv_data has been allocated
+     * so that a filter->close needing priv_data is never called without. */
+    bsfi = av_mallocz(sizeof(*bsfi));
+    if (!bsfi) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+    ctx->internal = bsfi;
+
+    bsfi->buffer_pkt = av_packet_alloc();
+    if (!bsfi->buffer_pkt) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
 
     *pctx = ctx;
     return 0;



More information about the ffmpeg-cvslog mailing list