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>
pull/75/merge
Michael Niedermayer 10 years ago
parent e56425d1a7
commit 4641ae352e
  1. 6
      libavformat/avidec.c
  2. 5
      libavformat/concatdec.c
  3. 5
      libavformat/hls.c
  4. 4
      libavformat/internal.h
  5. 5
      libavformat/libquvi.c
  6. 4
      libavformat/mpeg.c
  7. 7
      libavformat/rtpdec_asf.c
  8. 5
      libavformat/sapdec.c
  9. 13
      libavformat/utils.c

@ -1040,9 +1040,8 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt)
ast->sub_ctx->pb = pb; ast->sub_ctx->pb = pb;
av_assert0(!ast->sub_ctx->codec_whitelist && !ast->sub_ctx->format_whitelist); if (ff_copy_whitelists(ast->sub_ctx, s) < 0)
ast->sub_ctx-> codec_whitelist = av_strdup(s->codec_whitelist); goto error;
ast->sub_ctx->format_whitelist = av_strdup(s->format_whitelist);
if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) { if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {
ff_read_packet(ast->sub_ctx, &ast->sub_pkt); 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; return 1;
error: error:
av_freep(&ast->sub_ctx);
av_freep(&pb); av_freep(&pb);
} }
return 0; return 0;

@ -289,9 +289,8 @@ static int open_file(AVFormatContext *avf, unsigned fileno)
cat->avf->interrupt_callback = avf->interrupt_callback; cat->avf->interrupt_callback = avf->interrupt_callback;
av_assert0(!cat->avf->codec_whitelist && !cat->avf->format_whitelist); if ((ret = ff_copy_whitelists(cat->avf, avf)) < 0)
cat->avf-> codec_whitelist = av_strdup(avf->codec_whitelist); return ret;
cat->avf->format_whitelist = av_strdup(avf->format_whitelist);
if ((ret = avformat_open_input(&cat->avf, file->url, NULL, NULL)) < 0 || if ((ret = avformat_open_input(&cat->avf, file->url, NULL, NULL)) < 0 ||
(ret = avformat_find_stream_info(cat->avf, NULL)) < 0) { (ret = avformat_find_stream_info(cat->avf, NULL)) < 0) {

@ -1345,9 +1345,8 @@ static int hls_read_header(AVFormatContext *s)
pls->ctx->pb = &pls->pb; pls->ctx->pb = &pls->pb;
pls->stream_offset = stream_offset; pls->stream_offset = stream_offset;
av_assert0(!pls->ctx->codec_whitelist && !pls->ctx->format_whitelist); if ((ret = ff_copy_whitelists(pls->ctx, s)) < 0)
pls->ctx-> codec_whitelist = av_strdup(s->codec_whitelist); goto fail;
pls->ctx->format_whitelist = av_strdup(s->format_whitelist);
ret = avformat_open_input(&pls->ctx, pls->segments[0]->url, in_fmt, NULL); ret = avformat_open_input(&pls->ctx, pls->segments[0]->url, in_fmt, NULL);
if (ret < 0) if (ret < 0)

@ -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 */ #endif /* AVFORMAT_INTERNAL_H */

@ -76,9 +76,8 @@ static int libquvi_read_header(AVFormatContext *s)
if (rc != QUVI_OK) if (rc != QUVI_OK)
goto quvi_fail; goto quvi_fail;
av_assert0(!qc->fmtctx->codec_whitelist && !qc->fmtctx->format_whitelist); if ((ret = ff_copy_whitelists(qc->fmtctx, s)) < 0)
qc->fmtctx-> codec_whitelist = av_strdup(s->codec_whitelist); goto end;
qc->fmtctx->format_whitelist = av_strdup(s->format_whitelist);
ret = avformat_open_input(&qc->fmtctx, media_url, NULL, NULL); ret = avformat_open_input(&qc->fmtctx, media_url, NULL, NULL);
if (ret < 0) if (ret < 0)

@ -700,8 +700,8 @@ static int vobsub_read_header(AVFormatContext *s)
if (!vobsub->sub_ctx) if (!vobsub->sub_ctx)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
vobsub->sub_ctx-> codec_whitelist = av_strdup(s->codec_whitelist); if ((ret = ff_copy_whitelists(vobsub->sub_ctx, s)) < 0)
vobsub->sub_ctx->format_whitelist = av_strdup(s->format_whitelist); goto end;
ret = avformat_open_input(&vobsub->sub_ctx, sub_name, &ff_mpegps_demuxer, NULL); ret = avformat_open_input(&vobsub->sub_ctx, sub_name, &ff_mpegps_demuxer, NULL);
if (ret < 0) { if (ret < 0) {

@ -117,9 +117,10 @@ int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p)
rt->asf_ctx->pb = &pb; rt->asf_ctx->pb = &pb;
av_dict_set(&opts, "no_resync_search", "1", 0); av_dict_set(&opts, "no_resync_search", "1", 0);
av_assert0(!rt->asf_ctx->codec_whitelist && !rt->asf_ctx->format_whitelist); if ((ret = ff_copy_whitelists(rt->asf_ctx, s)) < 0) {
rt->asf_ctx-> codec_whitelist = av_strdup(s->codec_whitelist); av_dict_free(&opts);
rt->asf_ctx->format_whitelist = av_strdup(s->format_whitelist); return ret;
}
ret = avformat_open_input(&rt->asf_ctx, "", &ff_asf_demuxer, &opts); ret = avformat_open_input(&rt->asf_ctx, "", &ff_asf_demuxer, &opts);
av_dict_free(&opts); av_dict_free(&opts);

@ -160,9 +160,8 @@ static int sap_read_header(AVFormatContext *s)
sap->sdp_ctx->pb = &sap->sdp_pb; sap->sdp_ctx->pb = &sap->sdp_pb;
sap->sdp_ctx->interrupt_callback = s->interrupt_callback; sap->sdp_ctx->interrupt_callback = s->interrupt_callback;
av_assert0(!sap->sdp_ctx->codec_whitelist && !sap->sdp_ctx->format_whitelist); if ((ret = ff_copy_whitelists(sap->sdp_ctx, s)) < 0)
sap->sdp_ctx-> codec_whitelist = av_strdup(s->codec_whitelist); goto fail;
sap->sdp_ctx->format_whitelist = av_strdup(s->format_whitelist);
ret = avformat_open_input(&sap->sdp_ctx, "temp.sdp", infmt, NULL); ret = avformat_open_input(&sap->sdp_ctx, "temp.sdp", infmt, NULL);
if (ret < 0) if (ret < 0)

@ -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) static const AVCodec *find_decoder(AVFormatContext *s, AVStream *st, enum AVCodecID codec_id)
{ {
if (st->codec->codec) if (st->codec->codec)

Loading…
Cancel
Save