[FFmpeg-cvslog] avformat: Add and use ff_copy_whitelists()

Michael Niedermayer git at videolan.org
Fri Oct 24 19:44:29 CEST 2014


ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Fri Oct 24 19:23:23 2014 +0200| [4641ae352ec587355764ffd5c43dd0d0ebd47654] | committer: Michael Niedermayer

avformat: Add and use ff_copy_whitelists()

Fixes potential security issue in case of running out of memory

Found-by: ubitux
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

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

 libavformat/avidec.c     |    6 +++---
 libavformat/concatdec.c  |    5 ++---
 libavformat/hls.c        |    5 ++---
 libavformat/internal.h   |    4 ++++
 libavformat/libquvi.c    |    5 ++---
 libavformat/mpeg.c       |    4 ++--
 libavformat/rtpdec_asf.c |    7 ++++---
 libavformat/sapdec.c     |    5 ++---
 libavformat/utils.c      |   13 +++++++++++++
 9 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index e4f43a2..0cdcc08 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -1040,9 +1040,8 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt)
 
         ast->sub_ctx->pb = pb;
 
-        av_assert0(!ast->sub_ctx->codec_whitelist && !ast->sub_ctx->format_whitelist);
-        ast->sub_ctx-> codec_whitelist = av_strdup(s->codec_whitelist);
-        ast->sub_ctx->format_whitelist = av_strdup(s->format_whitelist);
+        if (ff_copy_whitelists(ast->sub_ctx, s) < 0)
+            goto error;
 
         if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {
             ff_read_packet(ast->sub_ctx, &ast->sub_pkt);
@@ -1056,6 +1055,7 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt)
         return 1;
 
 error:
+        av_freep(&ast->sub_ctx);
         av_freep(&pb);
     }
     return 0;
diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c
index ed959cf..2089883 100644
--- a/libavformat/concatdec.c
+++ b/libavformat/concatdec.c
@@ -289,9 +289,8 @@ static int open_file(AVFormatContext *avf, unsigned fileno)
 
     cat->avf->interrupt_callback = avf->interrupt_callback;
 
-    av_assert0(!cat->avf->codec_whitelist && !cat->avf->format_whitelist);
-    cat->avf-> codec_whitelist = av_strdup(avf->codec_whitelist);
-    cat->avf->format_whitelist = av_strdup(avf->format_whitelist);
+    if ((ret = ff_copy_whitelists(cat->avf, avf)) < 0)
+        return ret;
 
     if ((ret = avformat_open_input(&cat->avf, file->url, NULL, NULL)) < 0 ||
         (ret = avformat_find_stream_info(cat->avf, NULL)) < 0) {
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 80d9b5f..f17b826 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -1345,9 +1345,8 @@ static int hls_read_header(AVFormatContext *s)
         pls->ctx->pb       = &pls->pb;
         pls->stream_offset = stream_offset;
 
-        av_assert0(!pls->ctx->codec_whitelist && !pls->ctx->format_whitelist);
-        pls->ctx-> codec_whitelist = av_strdup(s->codec_whitelist);
-        pls->ctx->format_whitelist = av_strdup(s->format_whitelist);
+        if ((ret = ff_copy_whitelists(pls->ctx, s)) < 0)
+            goto fail;
 
         ret = avformat_open_input(&pls->ctx, pls->segments[0]->url, in_fmt, NULL);
         if (ret < 0)
diff --git a/libavformat/internal.h b/libavformat/internal.h
index f254e4c..28c29b0 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -412,5 +412,9 @@ enum AVWriteUncodedFrameFlags {
 
 };
 
+/**
+ * Copies the whilelists from one context to the other
+ */
+int ff_copy_whitelists(AVFormatContext *dst, AVFormatContext *src);
 
 #endif /* AVFORMAT_INTERNAL_H */
diff --git a/libavformat/libquvi.c b/libavformat/libquvi.c
index 633ff0b..0a593cc 100644
--- a/libavformat/libquvi.c
+++ b/libavformat/libquvi.c
@@ -76,9 +76,8 @@ static int libquvi_read_header(AVFormatContext *s)
     if (rc != QUVI_OK)
         goto quvi_fail;
 
-    av_assert0(!qc->fmtctx->codec_whitelist && !qc->fmtctx->format_whitelist);
-    qc->fmtctx-> codec_whitelist = av_strdup(s->codec_whitelist);
-    qc->fmtctx->format_whitelist = av_strdup(s->format_whitelist);
+    if ((ret = ff_copy_whitelists(qc->fmtctx, s)) < 0)
+        goto end;
 
     ret = avformat_open_input(&qc->fmtctx, media_url, NULL, NULL);
     if (ret < 0)
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 09af46e..369affd 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -700,8 +700,8 @@ static int vobsub_read_header(AVFormatContext *s)
     if (!vobsub->sub_ctx)
         return AVERROR(ENOMEM);
 
-    vobsub->sub_ctx-> codec_whitelist = av_strdup(s->codec_whitelist);
-    vobsub->sub_ctx->format_whitelist = av_strdup(s->format_whitelist);
+    if ((ret = ff_copy_whitelists(vobsub->sub_ctx, s)) < 0)
+        goto end;
 
     ret = avformat_open_input(&vobsub->sub_ctx, sub_name, &ff_mpegps_demuxer, NULL);
     if (ret < 0) {
diff --git a/libavformat/rtpdec_asf.c b/libavformat/rtpdec_asf.c
index f21197a..8fd2e24 100644
--- a/libavformat/rtpdec_asf.c
+++ b/libavformat/rtpdec_asf.c
@@ -117,9 +117,10 @@ int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p)
         rt->asf_ctx->pb      = &pb;
         av_dict_set(&opts, "no_resync_search", "1", 0);
 
-        av_assert0(!rt->asf_ctx->codec_whitelist && !rt->asf_ctx->format_whitelist);
-        rt->asf_ctx-> codec_whitelist = av_strdup(s->codec_whitelist);
-        rt->asf_ctx->format_whitelist = av_strdup(s->format_whitelist);
+        if ((ret = ff_copy_whitelists(rt->asf_ctx, s)) < 0) {
+            av_dict_free(&opts);
+            return ret;
+        }
 
         ret = avformat_open_input(&rt->asf_ctx, "", &ff_asf_demuxer, &opts);
         av_dict_free(&opts);
diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c
index dbef1d2..2dd8524 100644
--- a/libavformat/sapdec.c
+++ b/libavformat/sapdec.c
@@ -160,9 +160,8 @@ static int sap_read_header(AVFormatContext *s)
     sap->sdp_ctx->pb        = &sap->sdp_pb;
     sap->sdp_ctx->interrupt_callback = s->interrupt_callback;
 
-    av_assert0(!sap->sdp_ctx->codec_whitelist && !sap->sdp_ctx->format_whitelist);
-    sap->sdp_ctx-> codec_whitelist = av_strdup(s->codec_whitelist);
-    sap->sdp_ctx->format_whitelist = av_strdup(s->format_whitelist);
+    if ((ret = ff_copy_whitelists(sap->sdp_ctx, s)) < 0)
+        goto fail;
 
     ret = avformat_open_input(&sap->sdp_ctx, "temp.sdp", infmt, NULL);
     if (ret < 0)
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 995bcfc..61421c0 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -130,6 +130,19 @@ void av_format_inject_global_side_data(AVFormatContext *s)
     }
 }
 
+int ff_copy_whitelists(AVFormatContext *dst, AVFormatContext *src)
+{
+    av_assert0(!dst->codec_whitelist && !dst->format_whitelist);
+    dst-> codec_whitelist = av_strdup(src->codec_whitelist);
+    dst->format_whitelist = av_strdup(src->format_whitelist);
+    if (   (src-> codec_whitelist && !dst-> codec_whitelist)
+        || (src->format_whitelist && !dst->format_whitelist)) {
+        av_log(dst, AV_LOG_ERROR, "Failed to duplicate whitelist\n");
+        return AVERROR(ENOMEM);
+    }
+    return 0;
+}
+
 static const AVCodec *find_decoder(AVFormatContext *s, AVStream *st, enum AVCodecID codec_id)
 {
     if (st->codec->codec)



More information about the ffmpeg-cvslog mailing list