diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-10-24 19:23:23 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-10-24 19:23:23 +0200 |
commit | 4641ae352ec587355764ffd5c43dd0d0ebd47654 (patch) | |
tree | da175629ebf72bf55a504dd2d0240b1034892f4e /libavformat | |
parent | e56425d1a71828c32f7f355f0979534e1007078f (diff) | |
download | ffmpeg-4641ae352ec587355764ffd5c43dd0d0ebd47654.tar.gz |
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@gmx.at>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/avidec.c | 6 | ||||
-rw-r--r-- | libavformat/concatdec.c | 5 | ||||
-rw-r--r-- | libavformat/hls.c | 5 | ||||
-rw-r--r-- | libavformat/internal.h | 4 | ||||
-rw-r--r-- | libavformat/libquvi.c | 5 | ||||
-rw-r--r-- | libavformat/mpeg.c | 4 | ||||
-rw-r--r-- | libavformat/rtpdec_asf.c | 7 | ||||
-rw-r--r-- | libavformat/sapdec.c | 5 | ||||
-rw-r--r-- | libavformat/utils.c | 13 |
9 files changed, 34 insertions, 20 deletions
diff --git a/libavformat/avidec.c b/libavformat/avidec.c index e4f43a29a7..0cdcc08f65 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 ed959cf219..2089883307 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 80d9b5f016..f17b826f30 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 f254e4c016..28c29b0f4e 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 633ff0b470..0a593cc9cf 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 09af46e404..369affda0c 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 f21197aab2..8fd2e24afe 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 dbef1d2bee..2dd8524bce 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 995bcfc15c..61421c0f29 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) |