[FFmpeg-devel] [PATCH 2/2] avcodec: add avcodec_register_list() to register a list of codec/parser/bsf/hwaccel

Michael Niedermayer michaelni at gmx.at
Tue Sep 30 19:41:08 CEST 2014


This allows globally limiting the allowed entities for security purposes
by the application

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
 libavcodec/allcodecs.c |   49 ++++++++++++++++++++++++++++++++++--------------
 libavcodec/avcodec.h   |   20 ++++++++++++++++++++
 2 files changed, 55 insertions(+), 14 deletions(-)

diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 7650543..9fea0b9 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -27,51 +27,65 @@
 #include "config.h"
 #include "avcodec.h"
 #include "version.h"
+#include "libavutil/avstring.h"
 
 #define REGISTER_HWACCEL(X, x)                                          \
-    {                                                                   \
+    if (!list || av_match_list(AV_STRINGIFY(x##_hwaccel), list, ',')) { \
         extern AVHWAccel ff_##x##_hwaccel;                              \
-        if (CONFIG_##X##_HWACCEL)                                       \
+        if (CONFIG_##X##_HWACCEL) {                                     \
             av_register_hwaccel(&ff_##x##_hwaccel);                     \
+            found++;                                                    \
+        }                                                               \
     }
 
 #define REGISTER_ENCODER(X, x)                                          \
-    {                                                                   \
+    if (!list || av_match_list(AV_STRINGIFY(x##_encoder), list, ',')) { \
         extern AVCodec ff_##x##_encoder;                                \
-        if (CONFIG_##X##_ENCODER)                                       \
+        if (CONFIG_##X##_ENCODER) {                                     \
             avcodec_register(&ff_##x##_encoder);                        \
+            found++;                                                    \
+        }                                                               \
     }
 
 #define REGISTER_DECODER(X, x)                                          \
-    {                                                                   \
+    if (!list || av_match_list(AV_STRINGIFY(x##_decoder), list, ',')) { \
         extern AVCodec ff_##x##_decoder;                                \
-        if (CONFIG_##X##_DECODER)                                       \
+        if (CONFIG_##X##_DECODER) {                                     \
             avcodec_register(&ff_##x##_decoder);                        \
+            found++;                                                    \
+        }                                                               \
     }
 
 #define REGISTER_ENCDEC(X, x) REGISTER_ENCODER(X, x); REGISTER_DECODER(X, x)
 
 #define REGISTER_PARSER(X, x)                                           \
-    {                                                                   \
+    if (!list || av_match_list(AV_STRINGIFY(x##_parser), list, ',')) {  \
         extern AVCodecParser ff_##x##_parser;                           \
-        if (CONFIG_##X##_PARSER)                                        \
+        if (CONFIG_##X##_PARSER) {                                      \
             av_register_codec_parser(&ff_##x##_parser);                 \
+            found++;                                                    \
+        }                                                               \
     }
 
 #define REGISTER_BSF(X, x)                                              \
-    {                                                                   \
+    if (!list || av_match_list(AV_STRINGIFY(x##_bsf), list, ',')) {     \
         extern AVBitStreamFilter ff_##x##_bsf;                          \
-        if (CONFIG_##X##_BSF)                                           \
+        if (CONFIG_##X##_BSF) {                                         \
             av_register_bitstream_filter(&ff_##x##_bsf);                \
+            found++;                                                    \
+        }                                                               \
     }
 
-void avcodec_register_all(void)
+int avcodec_register_list(const char *list)
 {
-    static int initialized;
+    static const char *initialized;
+    const char *nonnull_list = list ? list : "all";
+    int found = 0;
 
     if (initialized)
-        return;
-    initialized = 1;
+        return strcmp(nonnull_list, initialized) ? -1 : 0;
+
+    initialized = nonnull_list;
 
     /* hardware accelerators */
     REGISTER_HWACCEL(H263_VAAPI,        h263_vaapi);
@@ -588,4 +602,11 @@ void avcodec_register_all(void)
     REGISTER_BSF(NOISE,                 noise);
     REGISTER_BSF(REMOVE_EXTRADATA,      remove_extradata);
     REGISTER_BSF(TEXT2MOVSUB,           text2movsub);
+
+    return found;
+}
+
+void avcodec_register_all(void)
+{
+    avcodec_register_list(NULL);
 }
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 94e82f7..b804460 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -3472,6 +3472,26 @@ void avcodec_register(AVCodec *codec);
 void avcodec_register_all(void);
 
 /**
+ * Registers only the specified list of ',' seperated entities
+ *
+ * @param list ',' seperated list of entities to register, the list used must
+ *       have a sufficient lifetime so future calls to avcodec_register_list()
+ *       can access it for comparission.
+ *
+ * @note What is registered with the first call to avcodec_register_list() is
+ *       permanent, future calls to avcodec_register_list() and
+ *       avcodec_register_all() cannot override it until application exit.
+ * @note This function is intended to be used for restricting the allowed
+ *       decoders and other entities for security purposes in end user
+ *       applications, it is not intended to be called by libraries.
+ *
+ * @returns the number of newly registered entities, or 0 if the exact same list
+ *          has been registered previously or negative value if a differnet list
+ *          is already registered.
+ */
+int avcodec_register_list(const char *list);
+
+/**
  * Allocate an AVCodecContext and set its fields to default values. The
  * resulting struct should be freed with avcodec_free_context().
  *
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list