avcodec: add codec_whitelist
authorMichael Niedermayer <michaelni@gmx.at>
Tue, 30 Sep 2014 21:24:52 +0000 (23:24 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 19 Oct 2014 02:36:52 +0000 (04:36 +0200)
This allows restricting decoders to a list of needed ones for improved security

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavcodec/avcodec.h
libavcodec/options_table.h
libavcodec/utils.c

index 6e44a9068b3079ea2d99a3b545747c9f083bdf76..42eb57b76a4cb96dbc7acfbba209ed3e6ad6cfa5 100644 (file)
@@ -3112,6 +3112,13 @@ typedef struct AVCodecContext {
      */
     uint8_t *dump_separator;
 
      */
     uint8_t *dump_separator;
 
+    /**
+     * ',' seperated list of allowed decoders.
+     * If NULL then all are allowed
+     * - encoding: unused
+     * - decoding: set by user through AVOPtions (NO direct access)
+     */
+    char *codec_whitelist;
 } AVCodecContext;
 
 AVRational av_codec_get_pkt_timebase         (const AVCodecContext *avctx);
 } AVCodecContext;
 
 AVRational av_codec_get_pkt_timebase         (const AVCodecContext *avctx);
index 840d054edc7ff50e67a6637eca13449b8f2c57e3..77841b55fe6876b2a264e2e19c432340aa4f6c9d 100644 (file)
@@ -487,6 +487,7 @@ static const AVOption avcodec_options[] = {
 {"tb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TB }, 0, 0, V|D|E, "field_order" },
 {"bt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BT }, 0, 0, V|D|E, "field_order" },
 {"dump_separator", "set information dump field separator", OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, A|V|S|D|E},
 {"tb", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_TB }, 0, 0, V|D|E, "field_order" },
 {"bt", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = AV_FIELD_BT }, 0, 0, V|D|E, "field_order" },
 {"dump_separator", "set information dump field separator", OFFSET(dump_separator), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, A|V|S|D|E},
+{"codec_whitelist", "List of decoders that are allowed to be used", OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str = NULL },  CHAR_MIN, CHAR_MAX, D },
 {NULL},
 };
 
 {NULL},
 };
 
index 93be575d27ae96040ad2964ee0fe702b9a96b55d..36ba118e7f2f56dadbf9f4bac16c26032172efb3 100644 (file)
@@ -1385,6 +1385,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
     if ((ret = av_opt_set_dict(avctx, &tmp)) < 0)
         goto free_and_end;
 
     if ((ret = av_opt_set_dict(avctx, &tmp)) < 0)
         goto free_and_end;
 
+    if (avctx->codec_whitelist && av_match_list(codec->name, avctx->codec_whitelist, ',') <= 0) {
+        av_log(avctx, AV_LOG_ERROR, "Codec not on whitelist\n");
+        ret = AVERROR(EINVAL);
+        goto free_and_end;
+    }
+
     // only call ff_set_dimensions() for non H.264/VP6F codecs so as not to overwrite previously setup dimensions
     if (!(avctx->coded_width && avctx->coded_height && avctx->width && avctx->height &&
           (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_VP6F))) {
     // only call ff_set_dimensions() for non H.264/VP6F codecs so as not to overwrite previously setup dimensions
     if (!(avctx->coded_width && avctx->coded_height && avctx->width && avctx->height &&
           (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_VP6F))) {