From patchwork Mon Dec 16 00:04:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 16819 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 94AB844A07A for ; Mon, 16 Dec 2019 02:04:56 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 802F568ABED; Mon, 16 Dec 2019 02:04:56 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f67.google.com (mail-wm1-f67.google.com [209.85.128.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 96D9668ABC5 for ; Mon, 16 Dec 2019 02:04:46 +0200 (EET) Received: by mail-wm1-f67.google.com with SMTP id b19so4827305wmj.4 for ; Sun, 15 Dec 2019 16:04:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Odw0NJXHwiVl1zbg2NQveK6ci1N4Id8H5Aojl/vXMR8=; b=RJsn1hokLGhEI7JmSVyP0JOqIhIh40SQWHMKdCmkHK2TGJaicge0BRExufFkRjEmWE wC+ofqCt/wZ7CI88dtCxW76I6qBG4hMxedprPovZqvDPzgxseb2TVzRPXez91+uRlsJ2 jnsFoJDQQsK04E1WyARrVCYGtUMvH12nFqv3/W6LaaI8mRTvIjuxkIrcDQ3y/UFFEu4x dMlUuWJ1aQoHDz83VHkD+2D+b9NfMDdGFzhVfAnufUY+3g/wV41cl/eJnhSWpLszgKey mXb6XetJjN3ztLm78vfi1qJAMHyKFJf6u5wESJjGNFqLD699mkwlGrMwk6aqb71ig4hw kn0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Odw0NJXHwiVl1zbg2NQveK6ci1N4Id8H5Aojl/vXMR8=; b=DpXLqfbJ/X9cfhMpkERjDOMO1iurGY+oTTqf/dcmeQnUd5hUbMYXExBz+HAmOUD2Mi lQIZ+WCUE16Vij7bsUvyQOjlGYcStTHR7YCIPUUSW7FrwqPRwnNGQ5J4R/WHD753rkU1 6pyaIDCw6aKuhEgFxFmFjsDuihYGViFh5XyoD3IjoHPFXuIxeionyghwKTCEk8cNbdY0 yZ5QDE6hUnY2JfPlQKCXPbPCnEjqz0oSEM5kgVD+JyuuYw8x3ueTlDfQUFPYoUthiuiK SU1obELh6jdgFtEmF9PnEyIrf9+aM6EUQEq+4hkWjE01CdO9CJgcXt3+5xmXqvRHApQP H0Ag== X-Gm-Message-State: APjAAAX9f+YZoBPqqsSvQblkAhau8Bicul8y6j/OBCWWqgPY6zc9LDRY 0N80wdlE4ep2gXSgT3z6AfOMvRCr X-Google-Smtp-Source: APXvYqx7JntoVOai8AAONHaUfkFMMNJSjzOcWxQzT40rhcaSUzO+vhz4S7ufDsoW/BNyigabN8f9Tg== X-Received: by 2002:a7b:cb97:: with SMTP id m23mr26441536wmi.37.1576454685810; Sun, 15 Dec 2019 16:04:45 -0800 (PST) Received: from sblaptop.fritz.box (ipbcc08e23.dynamic.kabel-deutschland.de. [188.192.142.35]) by smtp.gmail.com with ESMTPSA id s1sm19214442wmc.23.2019.12.15.16.04.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 Dec 2019 16:04:45 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Mon, 16 Dec 2019 01:04:09 +0100 Message-Id: <20191216000418.24707-8-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191216000418.24707-1-andreas.rheinhardt@gmail.com> References: <20191216000418.24707-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 07/16] avformat/hlsenc: Fix potential segfault upon allocation failure X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" 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 --- 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); } }