From patchwork Tue Feb 2 20:58:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 25350 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 D526E44968F for ; Tue, 2 Feb 2021 23:04:21 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A6E8F688385; Tue, 2 Feb 2021 23:04:21 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2B4C3688385 for ; Tue, 2 Feb 2021 23:04:15 +0200 (EET) Received: by mail-wm1-f48.google.com with SMTP id a16so2699818wmm.0 for ; Tue, 02 Feb 2021 13:04:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-language:content-transfer-encoding; bh=mDE65f+b/y5u5eh2iwAo8W1LN2fuXCL0L18eUibEWuU=; b=Pc7/vO+r6Zn/aQeCV2eaHnmExwyBAX8mxRCptfvIrszYsxOWW6nNiufz8ZvJWDHa9p 1u46MBy1tzOr4wvtlq9gHB7bhqhKvig4YtHHWY4d6mktEnjwyw/OQ7LjWb8D32c0s4MT grmeoySlExFxd0KiadFdgsgC+nd2B6m5Pa4coHNPYzXMaBYjJMD0eTEv7It8wLRFuGt3 Y/vWOiK5pDKRdWheT30pe4xMme7ZzFw1aOObL/aylsp1PXP856D94JChlkWJPebk6OaC rmqQVNE8zR65Ify3T4s90Tk/HDfNec+mMSx9OHon4el7X0NHmHa99rQEQWk0x+JEPVkn rJcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=mDE65f+b/y5u5eh2iwAo8W1LN2fuXCL0L18eUibEWuU=; b=qN6eCXVg2l8inyTNTYWbJaYe0Nv2DdF/14NMFb1Ew4goy6SKcQApngI7uKVmJ1JoKb UnkOSuIHl08lehP+ioCDGYICJaYlQrCsDft45gw9lTAMlJV5qYqbQPy/WwEW2+QOEiUw 1YabyVsz4vjwTUmdJ+ntM+8dEpyaR+sdgtMal6t1Fcdd0uuXguPlUQWTmUsfLoyq01/T uM35jliwBWgpz4jKt2vAENCOyeHs3Oj5SvMA0LvrySXSsH/1aE9vLA3ywJxcKhtLn7LT KujKMKJvSnu9WTaZBl0tc7KZ6zTp7IjLOmnq9CEy0ElcvYCpuFPek/5V0QN12yVgEB+W HUyQ== X-Gm-Message-State: AOAM5317O0CN5tdvpYuYKAZVTdKycNFX1d/X9PYGFhxQlE/1dy3IcHHB gtW4cHpLwK/1DqaQeo4hJIRHWMqxMJZp5w== X-Google-Smtp-Source: ABdhPJw49SAhZhr8BpzI3FQCmyvb7cI7PCxtvRrVJaZtsHSi/LeldzvQbiiNDaGmEr66djD/5Ub5Hg== X-Received: by 2002:a1c:1d8b:: with SMTP id d133mr5371302wmd.172.1612299492461; Tue, 02 Feb 2021 12:58:12 -0800 (PST) Received: from [192.168.0.3] (cpc91226-cmbg18-2-0-cust7.5-4.cable.virginm.net. [82.0.29.8]) by smtp.gmail.com with ESMTPSA id s64sm1038052wms.21.2021.02.02.12.58.11 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 02 Feb 2021 12:58:11 -0800 (PST) To: ffmpeg-devel@ffmpeg.org References: <20210201223116.11378-1-michael@niedermayer.cc> From: Mark Thompson Message-ID: <183412cf-2869-b70c-ef0f-170e4315d07a@jkqxz.net> Date: Tue, 2 Feb 2021 20:58:11 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.6.1 MIME-Version: 1.0 In-Reply-To: <20210201223116.11378-1-michael@niedermayer.cc> Content-Language: en-US Subject: [FFmpeg-devel] [PATCH] cbs_sei: Detect payload overflows when reading SEI messages 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" The top-level GetBitContext is sized for the whole NAL unit, so it fails to detect overflows where a payload continues into the following message. To fix that, we make a new context on the stack for reading each payload. --- On 01/02/2021 22:31, Michael Niedermayer wrote: > Fixes: Timeout > Fixes: 29892/clusterfuzz-testcase-minimized-ffmpeg_BSF_H264_REDUNDANT_PPS_fuzzer-6310830956216320 > > Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg > Signed-off-by: Michael Niedermayer > --- > libavcodec/cbs_sei_syntax_template.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/libavcodec/cbs_sei_syntax_template.c b/libavcodec/cbs_sei_syntax_template.c > index 9114e61ff6..3b9bc942f5 100644 > --- a/libavcodec/cbs_sei_syntax_template.c > +++ b/libavcodec/cbs_sei_syntax_template.c > @@ -178,6 +178,8 @@ static int FUNC(message)(CodedBitstreamContext *ctx, RWContext *rw, > GetBitContext tmp = *rw; > int trailing_bits, trailing_zero_bits; > > + if (8 * current->payload_size < bits_written) > + return AVERROR_INVALIDDATA; > bits_left = 8 * current->payload_size - bits_written; > if (bits_left > 8) > skip_bits_long(&tmp, bits_left - 8); > So it looks like the actual problem is that we don't detect payload overflow, so the calculation here underflows if the payload is invalid such that we read more bits than there actually are. How about this answer, which tries to fix the general problem by detecting overflow properly - does it fix your fuzzed case? Thanks, - Mark libavcodec/cbs_sei_syntax_template.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/libavcodec/cbs_sei_syntax_template.c b/libavcodec/cbs_sei_syntax_template.c index 9114e61ff6..0ef7b42ed9 100644 --- a/libavcodec/cbs_sei_syntax_template.c +++ b/libavcodec/cbs_sei_syntax_template.c @@ -238,6 +238,7 @@ static int FUNC(message_list)(CodedBitstreamContext *ctx, RWContext *rw, uint32_t payload_type = 0; uint32_t payload_size = 0; uint32_t tmp; + GetBitContext payload_gbc; while (show_bits(rw, 8) == 0xff) { fixed(8, ff_byte, 0xff); @@ -253,13 +254,27 @@ static int FUNC(message_list)(CodedBitstreamContext *ctx, RWContext *rw, xu(8, last_payload_size_byte, tmp, 0, 254, 0); payload_size += tmp; + // There must be space remaining for both the payload and + // the trailing bits on the SEI NAL unit. + if (payload_size + 1 > get_bits_left(rw) / 8) { + av_log(ctx->log_ctx, AV_LOG_ERROR, + "Invalid SEI message: payload_size too large " + "(%"PRIu32" bytes).\n", payload_size); + return AVERROR_INVALIDDATA; + } + CHECK(init_get_bits(&payload_gbc, rw->buffer, + get_bits_count(rw) + 8 * payload_size)); + skip_bits_long(&payload_gbc, get_bits_count(rw)); + CHECK(ff_cbs_sei_list_add(current)); message = ¤t->messages[k]; message->payload_type = payload_type; message->payload_size = payload_size; - CHECK(FUNC(message)(ctx, rw, message)); + CHECK(FUNC(message)(ctx, &payload_gbc, message)); + + skip_bits_long(rw, 8 * payload_size); if (!cbs_h2645_read_more_rbsp_data(rw)) break;