diff mbox series

[FFmpeg-devel,v4] fftools/opts: Avoid crash when opts could not be allocated

Message ID 20211208023507.26194-1-young_chelsea@163.com
State New
Headers show
Series [FFmpeg-devel,v4] fftools/opts: Avoid crash when opts could not be allocated | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc success Make fate finished

Commit Message

Yy Dec. 8, 2021, 2:35 a.m. UTC
If 'opts' could not be allocated, exiting the program to avoid crash when release it. 
Before setup_find_stream_info_opts(), checking 'orig_nb_streams' is > 0.

Reported-by: TOTE Robot <oslab@tsinghua.edu.cn>
Signed-off-by: Yu Yang <young_chelsea@163.com>
---
 fftools/cmdutils.c   | 4 +---
 fftools/cmdutils.h   | 4 ++--
 fftools/ffmpeg_opt.c | 5 +++--
 3 files changed, 6 insertions(+), 7 deletions(-)

Comments

Yy Dec. 13, 2021, 11:56 a.m. UTC | #1
Ping for patch v4: fftools/opts: Avoid crash when opts could not be allocated.

> 2021年12月8日 上午10:35,Yu Yang <young_chelsea@163.com> 写道:
> 
> If 'opts' could not be allocated, exiting the program to avoid crash when release it. 
> Before setup_find_stream_info_opts(), checking 'orig_nb_streams' is > 0.
> 
> Reported-by: TOTE Robot <oslab@tsinghua.edu.cn>
> Signed-off-by: Yu Yang <young_chelsea@163.com>
> ---
> fftools/cmdutils.c   | 4 +---
> fftools/cmdutils.h   | 4 ++--
> fftools/ffmpeg_opt.c | 5 +++--
> 3 files changed, 6 insertions(+), 7 deletions(-)
> 
> diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
> index 3c8e5a82cd..4b977f16e5 100644
> --- a/fftools/cmdutils.c
> +++ b/fftools/cmdutils.c
> @@ -2181,13 +2181,11 @@ AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
>     int i;
>     AVDictionary **opts;
> 
> -    if (!s->nb_streams)
> -        return NULL;
>     opts = av_calloc(s->nb_streams, sizeof(*opts));
>     if (!opts) {
>         av_log(NULL, AV_LOG_ERROR,
>                "Could not alloc memory for stream options.\n");
> -        return NULL;
> +        exit_program(1);
>     }
>     for (i = 0; i < s->nb_streams; i++)
>         opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codecpar->codec_id,
> diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h
> index 82cda208be..50eed9b13a 100644
> --- a/fftools/cmdutils.h
> +++ b/fftools/cmdutils.h
> @@ -430,8 +430,8 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
>  * Each dictionary will contain the options from codec_opts which can
>  * be applied to the corresponding stream codec context.
>  *
> - * @return pointer to the created array of dictionaries, NULL if it
> - * cannot be created
> + * @return pointer to the created array of dictionaries.
> + * Calls exit() on failure.
>  */
> AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
>                                            AVDictionary *codec_opts);
> diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
> index a703798586..aac40acb9f 100644
> --- a/fftools/ffmpeg_opt.c
> +++ b/fftools/ffmpeg_opt.c
> @@ -1191,9 +1191,10 @@ static int open_input_file(OptionsContext *o, const char *filename)
>         choose_decoder(o, ic, ic->streams[i]);
> 
>     if (find_stream_info) {
> -        AVDictionary **opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
> +        AVDictionary **opts = NULL;
>         int orig_nb_streams = ic->nb_streams;
> -
> +        if (orig_nb_streams > 0)
> +            opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
>         /* If not enough info to get the stream parameters, we decode the
>            first frames to get it. (used in mpeg case for example) */
>         ret = avformat_find_stream_info(ic, opts);
> -- 
> 2.33.1
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Andreas Rheinhardt Dec. 13, 2021, 12:12 p.m. UTC | #2
Yu Yang:
> If 'opts' could not be allocated, exiting the program to avoid crash when release it. 
> Before setup_find_stream_info_opts(), checking 'orig_nb_streams' is > 0.
> 
> Reported-by: TOTE Robot <oslab@tsinghua.edu.cn>
> Signed-off-by: Yu Yang <young_chelsea@163.com>
> ---
>  fftools/cmdutils.c   | 4 +---
>  fftools/cmdutils.h   | 4 ++--
>  fftools/ffmpeg_opt.c | 5 +++--
>  3 files changed, 6 insertions(+), 7 deletions(-)
> 
> diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
> index 3c8e5a82cd..4b977f16e5 100644
> --- a/fftools/cmdutils.c
> +++ b/fftools/cmdutils.c
> @@ -2181,13 +2181,11 @@ AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
>      int i;
>      AVDictionary **opts;
>  
> -    if (!s->nb_streams)
> -        return NULL;

Moving this check to the caller makes this a bit uglier and misses the
point that this function is also called from ffplay and ffprobe (where
they will cause unnecessary allocations of arrays with zero entries).

>      opts = av_calloc(s->nb_streams, sizeof(*opts));
>      if (!opts) {
>          av_log(NULL, AV_LOG_ERROR,
>                 "Could not alloc memory for stream options.\n");
> -        return NULL;
> +        exit_program(1);
>      }
>      for (i = 0; i < s->nb_streams; i++)
>          opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codecpar->codec_id,
> diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h
> index 82cda208be..50eed9b13a 100644
> --- a/fftools/cmdutils.h
> +++ b/fftools/cmdutils.h
> @@ -430,8 +430,8 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
>   * Each dictionary will contain the options from codec_opts which can
>   * be applied to the corresponding stream codec context.
>   *
> - * @return pointer to the created array of dictionaries, NULL if it
> - * cannot be created
> + * @return pointer to the created array of dictionaries.
> + * Calls exit() on failure.
>   */
>  AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
>                                             AVDictionary *codec_opts);
> diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
> index a703798586..aac40acb9f 100644
> --- a/fftools/ffmpeg_opt.c
> +++ b/fftools/ffmpeg_opt.c
> @@ -1191,9 +1191,10 @@ static int open_input_file(OptionsContext *o, const char *filename)
>          choose_decoder(o, ic, ic->streams[i]);
>  
>      if (find_stream_info) {
> -        AVDictionary **opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
> +        AVDictionary **opts = NULL;
>          int orig_nb_streams = ic->nb_streams;
> -
> +        if (orig_nb_streams > 0)
> +            opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
>          /* If not enough info to get the stream parameters, we decode the
>             first frames to get it. (used in mpeg case for example) */
>          ret = avformat_find_stream_info(ic, opts);
>
diff mbox series

Patch

diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index 3c8e5a82cd..4b977f16e5 100644
--- a/fftools/cmdutils.c
+++ b/fftools/cmdutils.c
@@ -2181,13 +2181,11 @@  AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
     int i;
     AVDictionary **opts;
 
-    if (!s->nb_streams)
-        return NULL;
     opts = av_calloc(s->nb_streams, sizeof(*opts));
     if (!opts) {
         av_log(NULL, AV_LOG_ERROR,
                "Could not alloc memory for stream options.\n");
-        return NULL;
+        exit_program(1);
     }
     for (i = 0; i < s->nb_streams; i++)
         opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codecpar->codec_id,
diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h
index 82cda208be..50eed9b13a 100644
--- a/fftools/cmdutils.h
+++ b/fftools/cmdutils.h
@@ -430,8 +430,8 @@  AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
  * Each dictionary will contain the options from codec_opts which can
  * be applied to the corresponding stream codec context.
  *
- * @return pointer to the created array of dictionaries, NULL if it
- * cannot be created
+ * @return pointer to the created array of dictionaries.
+ * Calls exit() on failure.
  */
 AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
                                            AVDictionary *codec_opts);
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index a703798586..aac40acb9f 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -1191,9 +1191,10 @@  static int open_input_file(OptionsContext *o, const char *filename)
         choose_decoder(o, ic, ic->streams[i]);
 
     if (find_stream_info) {
-        AVDictionary **opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
+        AVDictionary **opts = NULL;
         int orig_nb_streams = ic->nb_streams;
-
+        if (orig_nb_streams > 0)
+            opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
         /* If not enough info to get the stream parameters, we decode the
            first frames to get it. (used in mpeg case for example) */
         ret = avformat_find_stream_info(ic, opts);