[FFmpeg-devel] [PATCH 07/16] avformat/hlsenc: Fix potential segfault upon allocation failure
Steven Liu
lq at chinaffmpeg.org
Mon Dec 23 06:58:45 EET 2019
> 在 2019年12月16日,08:04,Andreas Rheinhardt <andreas.rheinhardt at gmail.com> 写道:
>
> The hls muxer allocates an array of VariantStreams, a structure that
> contains pointers to objects that need to be freed on their own. This
> means that the number of allocated VariantStreams needs to be correct
> when they are freed; yet the number of VariantStreams is set in
> update_variant_stream_info() resp. parse_variant_stream_mapstring()
> before the allocation has been checked for success, so that upon error
> an attempt would be made to free the objects whose pointers are
> positioned at position NULL (the location of VariantStreams) +
> offsetof(VariantStream, the corresponding pointer).
>
> Furthermore d1fe1344 added another possibility for the first function
> to leave an inconsistent state behind: If an allocation of one of the
> objects referenced by the VariantStream fails, the VariantStream will be
> freed, but the number of allocated VariantStreams isn't reset, leading
> to the same problem as above. (This was done in the mistaken belief that
> the VariantStreams array would leak otherwise.)
>
> Essentially the same also happens for the number of cc-streams. It has
> been fixed, too.
>
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
> ---
> libavformat/hlsenc.c | 21 ++++++++++-----------
> 1 file changed, 10 insertions(+), 11 deletions(-)
>
> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> index 62f66c4c65..7fcc71264b 100644
> --- a/libavformat/hlsenc.c
> +++ b/libavformat/hlsenc.c
> @@ -1875,7 +1875,7 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
> VariantStream *vs;
> int stream_index, i, j;
> enum AVMediaType codec_type;
> - int nb_varstreams, nb_streams;
> + int nb_varstreams = 0, nb_streams;
> char *p, *q, *saveptr1, *saveptr2, *varstr, *keyval;
> const char *val;
>
> @@ -1900,13 +1900,14 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
> q = p;
> while (av_strtok(q, " \t", &saveptr1)) {
> q = NULL;
> - hls->nb_varstreams++;
> + nb_varstreams++;
> }
> av_freep(&p);
>
> - hls->var_streams = av_mallocz(sizeof(*hls->var_streams) * hls->nb_varstreams);
> + hls->var_streams = av_mallocz(sizeof(*hls->var_streams) * nb_varstreams);
> if (!hls->var_streams)
> return AVERROR(ENOMEM);
> + hls->nb_varstreams = nb_varstreams;
>
> p = hls->var_stream_map;
> nb_varstreams = 0;
> @@ -2011,7 +2012,7 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
> static int parse_cc_stream_mapstring(AVFormatContext *s)
> {
> HLSContext *hls = s->priv_data;
> - int nb_ccstreams;
> + int nb_ccstreams = 0;
> char *p, *q, *ccstr, *keyval;
> char *saveptr1 = NULL, *saveptr2 = NULL;
> const char *val;
> @@ -2024,13 +2025,14 @@ static int parse_cc_stream_mapstring(AVFormatContext *s)
> q = p;
> while (av_strtok(q, " \t", &saveptr1)) {
> q = NULL;
> - hls->nb_ccstreams++;
> + nb_ccstreams++;
> }
> av_freep(&p);
>
> - hls->cc_streams = av_mallocz(sizeof(*hls->cc_streams) * hls->nb_ccstreams);
> + hls->cc_streams = av_mallocz(sizeof(*hls->cc_streams) * nb_ccstreams);
> if (!hls->cc_streams)
> return AVERROR(ENOMEM);
> + hls->nb_ccstreams = nb_ccstreams;
>
> p = hls->cc_stream_map;
> nb_ccstreams = 0;
> @@ -2106,18 +2108,16 @@ static int update_variant_stream_info(AVFormatContext *s)
> return parse_variant_stream_mapstring(s);
> } else {
> //By default, a single variant stream with all the codec streams is created
> - hls->nb_varstreams = 1;
> - hls->var_streams = av_mallocz(sizeof(*hls->var_streams) *
> - hls->nb_varstreams);
> + hls->var_streams = av_mallocz(sizeof(*hls->var_streams));
> if (!hls->var_streams)
> return AVERROR(ENOMEM);
> + hls->nb_varstreams = 1;
>
> hls->var_streams[0].var_stream_idx = 0;
> hls->var_streams[0].nb_streams = s->nb_streams;
> hls->var_streams[0].streams = av_mallocz(sizeof(AVStream *) *
> hls->var_streams[0].nb_streams);
> if (!hls->var_streams[0].streams) {
> - av_freep(&hls->var_streams);
> return AVERROR(ENOMEM);
> }
>
> @@ -2125,7 +2125,6 @@ static int update_variant_stream_info(AVFormatContext *s)
> if (hls->nb_ccstreams) {
> hls->var_streams[0].ccgroup = av_strdup(hls->cc_streams[0].ccgroup);
> if (!hls->var_streams[0].ccgroup) {
> - av_freep(&hls->var_streams);
> return AVERROR(ENOMEM);
> }
> }
> --
> 2.20.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
LGTM
Thanks
Steven
More information about the ffmpeg-devel
mailing list