[FFmpeg-trac] #10459(avfilter:new): set_string_bool() overwrites memory.

FFmpeg trac at avcodec.org
Mon Jul 10 22:19:54 EEST 2023


#10459: set_string_bool() overwrites memory.
----------------------------------+--------------------------------------
             Reporter:  Wodzu     |                     Type:  defect
               Status:  new       |                 Priority:  normal
            Component:  avfilter  |                  Version:  git-master
             Keywords:            |               Blocked By:
             Blocking:            |  Reproduced by developer:  0
Analyzed by developer:  0         |
----------------------------------+--------------------------------------
 Summary of the bug:

 I am playing with ffmpeg and I wrote a custom filter based on the
 documentation. I've noticed erroneous behavior during function chain:
 graph_opts_apply->filter_opt_apply->filter_opt_apply->av_opt_set->set_string_bool
 for my bool option.

 Here is the definition of my context and options:

 {{{
 typedef struct FoobarContext {
     const AVClass *class;
     void* some_pointer;
     char* opt_1;
     char* opt_2;
     char* opt_3;
     char* opt_4;
     char* opt_5;
     float opt_6;
     float opt_7;
     float opt_8;
     bool opt_9;
     int opt_10;
     bool opt_11;
     bool opt_12;
     bool opt_13;
     bool opt_14;
 } FoobarContext;


 #define OFFSET(x) offsetof(FoobarContext, x)
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 static const AVOption foobar_options[] = {
     { "opt_1", "test", OFFSET(opt_1), AV_OPT_TYPE_STRING, {.str = NULL },
 0, 0, FLAGS},
     { "opt_2",  "test",  OFFSET(opt_2), AV_OPT_TYPE_STRING, {.str = NULL
 }, 0, 0, FLAGS},
     { "opt_3",  "test",  OFFSET(opt_3), AV_OPT_TYPE_STRING, {.str = NULL
 }, 0, 0, FLAGS},
     { "opt_4",  "test",  OFFSET(opt_4), AV_OPT_TYPE_STRING, {.str = "" },
 0, 0, FLAGS},
     { "opt_5",  "test",  OFFSET(opt_5), AV_OPT_TYPE_STRING, {.str = NULL
 }, 0, 0, FLAGS},
     { "opt_6",  "test",  OFFSET(opt_6), AV_OPT_TYPE_FLOAT, {.dbl = 0.01 },
 0, 1, FLAGS},
     { "opt_7",  "test",  OFFSET(opt_7), AV_OPT_TYPE_FLOAT, {.dbl = 0.01 },
 0, 1, FLAGS},
     { "opt_8",  "test",  OFFSET(opt_8), AV_OPT_TYPE_FLOAT, {.dbl = 0.45 },
 0, 1, FLAGS},
     { "opt_9",  "test",  OFFSET(opt_9), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0,
 1, FLAGS},
     { "opt_10",  "test",  OFFSET(opt_10), AV_OPT_TYPE_INT, {.i64 = 0 }, 0,
 10, FLAGS},
     { "opt_11",  "test",  OFFSET(opt_11), AV_OPT_TYPE_BOOL, {.i64 = 0 },
 0, 1, FLAGS},
     { "opt_12",  "test",  OFFSET(opt_12), AV_OPT_TYPE_BOOL, {.i64 = 1 },
 0, 1, FLAGS},
     { "opt_13",  "test",  OFFSET(opt_13), AV_OPT_TYPE_BOOL, {.i64 = 1 },
 0, 1, FLAGS},
     { "opt_14",  "test",  OFFSET(opt_14), AV_OPT_TYPE_BOOL, {.i64 = 1 },
 0, 1, FLAGS},
     { NULL }
 };

 }}}


 As you can see, from opt_11 until opt_14 we have bool options. OFFSET
 macro is creating offset on one byte boundary for these fields. So for
 opt_11 the offset is 76, for opt_12 offset is 77, for opt_13 offset is 78
 and (unsurprisingly at that point) for opt_14 offset is 79.

 The problem is that function set_string_bool(void *obj, const AVOption *o,
 const char *val, int *dst)
 is setting value of dst which is pointer to int. int is 4 byte long so it
 is overwriting default values of other 3 options as well.

 How to reproduce:
 Either find existing filter that contain grouped bool options or implement
 a simple pass through filter with the options above.

 Then run command like this:

 {{{
 % ffmpeg -i -i http://samples.ffmpeg.org/image-samples/lena.pnm
 "foobar=opt_11=y" foobar.png
 ffmpeg version N-110411-gaf8be7bf43 Copyright (c) 2000-2023 the FFmpeg
 developers
   built with gcc 11 (Ubuntu 11.3.0-1ubuntu1~22.04.1)

 }}}

 Guides to fix: change dst function parameter to uint8_t* , change "int n"
 variable to be type of bool.
-- 
Ticket URL: <https://trac.ffmpeg.org/ticket/10459>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list