From patchwork Wed Jan 31 18:20:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Niedermayer X-Patchwork-Id: 7457 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.156.27 with SMTP id q27csp2047276jak; Wed, 31 Jan 2018 10:20:40 -0800 (PST) X-Google-Smtp-Source: AH8x226MRUKQ3NUMn3xcVD1oe/TiFj8V9xOZtHkqNwvX4evSiC0JU1g7V1B0QEcQKeN45d/TbFQA X-Received: by 10.28.71.135 with SMTP id m7mr24654786wmi.115.1517422840522; Wed, 31 Jan 2018 10:20:40 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517422840; cv=none; d=google.com; s=arc-20160816; b=vBIbq6diTPqsgp/HeFwa2yfReweKiFC+QyjzAbc9bNDABKjd33LQEFgwix29TxgJBf kTC4q1GFm5Yixg4kxZnUaPTxxR/MfFRKo76Et7j+sUyjXTFcclHuLPLRBms1G/4ZLb1q +rg2GdVd219BUzMjjTFD8cUHch6HnIUdnzuafKXdecZw0hytmQT3n+ag7h4pOg+vfjTM GRFLPIlVqNL1st3jBCPoVlTupBqhlpWFpX0WwPQtDvQsJIxT/UhmC1xzG2khKpXYOIof N91NUiWcgiRLXIxRXTPnVENaigIfFpzX3MZtgKBibgznb8I2Kc46uIC71oLZ5cOFrf5E 6i1Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:delivered-to :arc-authentication-results; bh=0drHz4lvSdfZwfqMdiEHtyaIXFTz4Y0tQwUQda3H5Hs=; b=wmFv4DuxNLSe7TZnN8dxd4/40diUjoi1Y2MUkzr5X+cwv+gS90LZWetNd/FASd+dX5 LrYvi+WAMdae8RxBKLMhqWVCEu8smtKFJeZzeKiKRUYuz1j6tjG2DLRr/opTcFaap9i1 WrHpxo/JKpVMdB91cteYx2/o/UeivFLioAlUhtaHy+RCg9oSnHsELgiYLNvaoS5VKvFY t1PLmaohzXFxxviCdBBECu6x/jxT1VtWjS1wm3vYJrTBo4AYifNO3lmggyQVhtf/SfkJ 0YXvOu1lZ+b9PLmmyvjL6JxgR4KwPnH8R93q64jJI6iKV+J2JWiVBcGM674uRJXqYTSg j+oQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id c49si11640182wra.212.2018.01.31.10.20.40; Wed, 31 Jan 2018 10:20:40 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 08A19689892; Wed, 31 Jan 2018 20:20:26 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from vie01a-qmta-pe01-1.mx.upcmail.net (vie01a-qmta-pe01-1.mx.upcmail.net [62.179.121.178]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2319A6882FB for ; Wed, 31 Jan 2018 20:20:20 +0200 (EET) Received: from [172.31.218.40] (helo=vie01a-dmta-pe04-1.mx.upcmail.net) by vie01a-pqmta-pe01.mx.upcmail.net with esmtp (Exim 4.88) (envelope-from ) id 1egwzh-0005Ks-8e for ffmpeg-devel@ffmpeg.org; Wed, 31 Jan 2018 19:20:25 +0100 Received: from [172.31.216.43] (helo=vie01a-pemc-psmtp-pe01) by vie01a-dmta-pe04.mx.upcmail.net with esmtp (Exim 4.88) (envelope-from ) id 1egwzb-0002Y4-DD for ffmpeg-devel@ffmpeg.org; Wed, 31 Jan 2018 19:20:19 +0100 Received: from localhost ([213.47.41.20]) by vie01a-pemc-psmtp-pe01 with SMTP @ mailcloud.upcmail.net id 56LB1x00J0S5wYM016LCdD; Wed, 31 Jan 2018 19:20:12 +0100 X-SourceIP: 213.47.41.20 From: Michael Niedermayer To: FFmpeg development discussions and patches Date: Wed, 31 Jan 2018 19:20:08 +0100 Message-Id: <20180131182010.8745-1-michael@niedermayer.cc> X-Mailer: git-send-email 2.16.1 Subject: [FFmpeg-devel] [PATCH 1/3] avcodec/exr: Fix memleaks in decode_header() 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Fixes: 4793/clusterfuzz-testcase-minimized-5707366629638144 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/exr.c | 82 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 26 deletions(-) diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 454dc74cfb..cafd179cbd 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -1306,6 +1306,7 @@ static int decode_header(EXRContext *s, AVFrame *frame) AVDictionary *metadata = NULL; int magic_number, version, i, flags, sar = 0; int layer_match = 0; + int ret; s->current_channel_offset = 0; s->xmin = ~0; @@ -1364,8 +1365,10 @@ static int decode_header(EXRContext *s, AVFrame *frame) if ((var_size = check_header_variable(s, "channels", "chlist", 38)) >= 0) { GetByteContext ch_gb; - if (!var_size) - return AVERROR_INVALIDDATA; + if (!var_size) { + ret = AVERROR_INVALIDDATA; + goto fail; + } bytestream2_init(&ch_gb, s->gb.buffer, var_size); @@ -1424,14 +1427,16 @@ static int decode_header(EXRContext *s, AVFrame *frame) if (bytestream2_get_bytes_left(&ch_gb) < 4) { av_log(s->avctx, AV_LOG_ERROR, "Incomplete header.\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } current_pixel_type = bytestream2_get_le32(&ch_gb); if (current_pixel_type >= EXR_UNKNOWN) { avpriv_report_missing_feature(s->avctx, "Pixel type %d", current_pixel_type); - return AVERROR_PATCHWELCOME; + ret = AVERROR_PATCHWELCOME; + goto fail; } bytestream2_skip(&ch_gb, 4); @@ -1442,7 +1447,8 @@ static int decode_header(EXRContext *s, AVFrame *frame) avpriv_report_missing_feature(s->avctx, "Subsampling %dx%d", xsub, ysub); - return AVERROR_PATCHWELCOME; + ret = AVERROR_PATCHWELCOME; + goto fail; } if (channel_index >= 0 && s->channel_offsets[channel_index] == -1) { /* channel has not been previously assigned */ @@ -1450,7 +1456,8 @@ static int decode_header(EXRContext *s, AVFrame *frame) s->pixel_type != current_pixel_type) { av_log(s->avctx, AV_LOG_ERROR, "RGB channels not of the same depth.\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } s->pixel_type = current_pixel_type; s->channel_offsets[channel_index] = s->current_channel_offset; @@ -1458,8 +1465,10 @@ static int decode_header(EXRContext *s, AVFrame *frame) s->channels = av_realloc(s->channels, ++s->nb_channels * sizeof(EXRChannel)); - if (!s->channels) - return AVERROR(ENOMEM); + if (!s->channels) { + ret = AVERROR(ENOMEM);; + goto fail; + } channel = &s->channels[s->nb_channels - 1]; channel->pixel_type = current_pixel_type; channel->xsub = xsub; @@ -1484,7 +1493,8 @@ static int decode_header(EXRContext *s, AVFrame *frame) av_log(s->avctx, AV_LOG_ERROR, "Missing green channel.\n"); if (s->channel_offsets[2] < 0) av_log(s->avctx, AV_LOG_ERROR, "Missing blue channel.\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } } @@ -1493,8 +1503,10 @@ static int decode_header(EXRContext *s, AVFrame *frame) continue; } else if ((var_size = check_header_variable(s, "dataWindow", "box2i", 31)) >= 0) { - if (!var_size) - return AVERROR_INVALIDDATA; + if (!var_size) { + ret = AVERROR_INVALIDDATA; + goto fail; + } s->xmin = bytestream2_get_le32(&s->gb); s->ymin = bytestream2_get_le32(&s->gb); @@ -1506,8 +1518,10 @@ static int decode_header(EXRContext *s, AVFrame *frame) continue; } else if ((var_size = check_header_variable(s, "displayWindow", "box2i", 34)) >= 0) { - if (!var_size) - return AVERROR_INVALIDDATA; + if (!var_size) { + ret = AVERROR_INVALIDDATA; + goto fail; + } bytestream2_skip(&s->gb, 8); s->w = bytestream2_get_le32(&s->gb) + 1; @@ -1517,29 +1531,36 @@ static int decode_header(EXRContext *s, AVFrame *frame) } else if ((var_size = check_header_variable(s, "lineOrder", "lineOrder", 25)) >= 0) { int line_order; - if (!var_size) - return AVERROR_INVALIDDATA; + if (!var_size) { + ret = AVERROR_INVALIDDATA; + goto fail; + } line_order = bytestream2_get_byte(&s->gb); av_log(s->avctx, AV_LOG_DEBUG, "line order: %d.\n", line_order); if (line_order > 2) { av_log(s->avctx, AV_LOG_ERROR, "Unknown line order.\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } continue; } else if ((var_size = check_header_variable(s, "pixelAspectRatio", "float", 31)) >= 0) { - if (!var_size) - return AVERROR_INVALIDDATA; + if (!var_size) { + ret = AVERROR_INVALIDDATA; + goto fail; + } sar = bytestream2_get_le32(&s->gb); continue; } else if ((var_size = check_header_variable(s, "compression", "compression", 29)) >= 0) { - if (!var_size) - return AVERROR_INVALIDDATA; + if (!var_size) { + ret = AVERROR_INVALIDDATA; + goto fail; + } if (s->compression == EXR_UNKN) s->compression = bytestream2_get_byte(&s->gb); @@ -1566,13 +1587,15 @@ static int decode_header(EXRContext *s, AVFrame *frame) if (s->tile_attr.level_mode >= EXR_TILE_LEVEL_UNKNOWN){ avpriv_report_missing_feature(s->avctx, "Tile level mode %d", s->tile_attr.level_mode); - return AVERROR_PATCHWELCOME; + ret = AVERROR_PATCHWELCOME; + goto fail; } if (s->tile_attr.level_round >= EXR_TILE_ROUND_UNKNOWN) { avpriv_report_missing_feature(s->avctx, "Tile level round %d", s->tile_attr.level_round); - return AVERROR_PATCHWELCOME; + ret = AVERROR_PATCHWELCOME; + goto fail; } continue; @@ -1589,7 +1612,8 @@ static int decode_header(EXRContext *s, AVFrame *frame) // Check if there are enough bytes for a header if (bytestream2_get_bytes_left(&s->gb) <= 9) { av_log(s->avctx, AV_LOG_ERROR, "Incomplete header\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } // Process unknown variables @@ -1604,19 +1628,22 @@ static int decode_header(EXRContext *s, AVFrame *frame) if (s->compression == EXR_UNKN) { av_log(s->avctx, AV_LOG_ERROR, "Missing compression attribute.\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } if (s->is_tile) { if (s->tile_attr.xSize < 1 || s->tile_attr.ySize < 1) { av_log(s->avctx, AV_LOG_ERROR, "Invalid tile attribute.\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } } if (bytestream2_get_bytes_left(&s->gb) <= 0) { av_log(s->avctx, AV_LOG_ERROR, "Incomplete frame.\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } frame->metadata = metadata; @@ -1624,6 +1651,9 @@ static int decode_header(EXRContext *s, AVFrame *frame) // aaand we are done bytestream2_skip(&s->gb, 1); return 0; +fail: + av_dict_free(&metadata); + return ret; } static int decode_frame(AVCodecContext *avctx, void *data,