From patchwork Sat Aug 29 22:36:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Niedermayer X-Patchwork-Id: 22003 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 3267544A565 for ; Sun, 30 Aug 2020 01:37:40 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0765C689A02; Sun, 30 Aug 2020 01:37:40 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from vie01a-dmta-pe06-2.mx.upcmail.net (vie01a-dmta-pe06-2.mx.upcmail.net [84.116.36.15]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 02E81680A43 for ; Sun, 30 Aug 2020 01:37:32 +0300 (EEST) Received: from [172.31.216.235] (helo=vie01a-pemc-psmtp-pe12.mail.upcmail.net) by vie01a-dmta-pe06.mx.upcmail.net with esmtp (Exim 4.92) (envelope-from ) id 1kC9TY-0008I9-0A for ffmpeg-devel@ffmpeg.org; Sun, 30 Aug 2020 00:37:32 +0200 Received: from localhost ([213.47.68.29]) by vie01a-pemc-psmtp-pe12.mail.upcmail.net with ESMTP id C9SZkbb7EIr7GC9SZkOVkg; Sun, 30 Aug 2020 00:36:32 +0200 X-Env-Mailfrom: michael@niedermayer.cc X-Env-Rcptto: ffmpeg-devel@ffmpeg.org X-SourceIP: 213.47.68.29 X-CNFS-Analysis: v=2.3 cv=QN4WuTDL c=1 sm=1 tr=0 a=2hcxjKEKjp0CzLx6oWAm4g==:117 a=2hcxjKEKjp0CzLx6oWAm4g==:17 a=MKtGQD3n3ToA:10 a=1oJP67jkp3AA:10 a=GEAsPZ9sns4A:10 a=ZZnuYtJkoWoA:10 a=dBIKjkU3tknC4taviDQA:9 From: Michael Niedermayer To: FFmpeg development discussions and patches Date: Sun, 30 Aug 2020 00:36:31 +0200 Message-Id: <20200829223631.18415-1-michael@niedermayer.cc> X-Mailer: git-send-email 2.17.1 X-CMAE-Envelope: MS4wfNFuz0dOUaA2boCJI9Jyhar4mMXTnOQ6VQDbf2jdsCHRojAGyohe8snvC+btNz0BHwP7Q/ZlnyCpOB3rfb01/LdPg2HluE8labN2fI1zeVsgoWgwAck9 ePhYf5PVRFQfURYVW8m3s5E6IB51PThHGG1/z/GKpZhgxjQfOS+6q3sJ Subject: [FFmpeg-devel] [PATCH v2] avcodec/cfhd: More strictly check tag order 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" This is based on the encoder and a small number of CFHD sample files It should make the decoder more robust against crafted input. Due to the lack of a proper specification it is possible that this may be too strict and may need to be tuned as files not following this ordering are found. Signed-off-by: Michael Niedermayer --- libavcodec/cfhd.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++ libavcodec/cfhd.h | 3 +++ 2 files changed, 69 insertions(+) diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c index ea35f03869..c36edb9ef8 100644 --- a/libavcodec/cfhd.c +++ b/libavcodec/cfhd.c @@ -361,6 +361,64 @@ static int alloc_buffers(AVCodecContext *avctx) return 0; } +static int handle_tag_order(CFHDContext *s, int tag, int data) +{ + int atag = abs(tag); + // We do not restrict tags outside the enum + if (atag >= LastTag) + return 0; + + if (s->previous_marker == 0x88888888) { + if (tag >= 1 && tag <= 17 || tag >= 19 && tag <= 23 || atag >= 63 && atag <= 66 || atag >= 68 && atag <= 71 || atag == 73 || atag >= 79 && atag <= 81 || atag >= 83 && atag <= 85 || atag >= 91 && atag <= 93) { + ; + } else if (tag == BitstreamMarker && data == 0x1a4a) { + ; + } else + return AVERROR_INVALIDDATA; + } else if (s->previous_marker == 0x1a4a) { + if (tag >= 25 && tag <= 36) { + ; + } else if (tag == BitstreamMarker && data == 0xf0f) { + ; + } else + return AVERROR_INVALIDDATA; + } else if (s->previous_marker == 0xf0f) { + if (tag != BitstreamMarker || data != 0x1b4b) + return AVERROR_INVALIDDATA; + } else if (s->previous_marker == 0x1b4b) { + if (tag != BitstreamMarker || data != 0xd0d) + return AVERROR_INVALIDDATA; + } else if (s->previous_marker == 0xd0d) { + if (tag >= 37 && tag <= 47) { + ; + } else if (tag == BitstreamMarker && data == 0xe0e) { + ; + } else + return AVERROR_INVALIDDATA; + } else if (s->previous_marker == 0xe0e) { + if (tag >= 48 && tag <= 56 || tag == BandCodingFlags) { + ; + } else if (-tag >= 74 && -tag <= 76) { + ; + } else if (tag == BitstreamMarker && (data == 0xc0c || data == 0xe0e)) { + ; + } else + return AVERROR_INVALIDDATA; + } else if (s->previous_marker == 0xc0c) { + if (tag == 1 || tag == 18 || tag == 24 || tag == 62 ) { + ; + } else if (tag == BitstreamMarker && (data == 0xd0d || data == 0x1a4a)) { + ; + } else + return AVERROR_INVALIDDATA; + } else + return AVERROR_INVALIDDATA; + + if (tag == BitstreamMarker) + s->previous_marker = data; + return 0; +} + static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { @@ -374,6 +432,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, init_frame_defaults(s); s->planes = av_pix_fmt_count_planes(s->coded_format); + s->previous_marker = 0x88888888; bytestream2_init(&gb, avpkt->data, avpkt->size); @@ -385,6 +444,13 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, uint16_t abstag = abs(tag); int8_t abs_tag8 = abs(tag8); uint16_t data = bytestream2_get_be16(&gb); + + ret = handle_tag_order(s, tag, data); + if (ret < 0) { + av_log(avctx, AV_LOG_DEBUG, "Unexpected TAG %d data %X in %X\n", tag, data, s->previous_marker); + return ret; + } + if (abs_tag8 >= 0x60 && abs_tag8 <= 0x6f) { av_log(avctx, AV_LOG_DEBUG, "large len %x\n", ((tagu & 0xff) << 16) | data); } else if (tag == SampleFlags) { diff --git a/libavcodec/cfhd.h b/libavcodec/cfhd.h index 8ea91270cd..c46ab01c17 100644 --- a/libavcodec/cfhd.h +++ b/libavcodec/cfhd.h @@ -93,6 +93,7 @@ enum CFHDParam { DisplayHeight = 85, ChannelWidth = 104, ChannelHeight = 105, + LastTag, }; #define VLC_BITS 9 @@ -184,6 +185,8 @@ typedef struct CFHDContext { Plane plane[4]; Peak peak; + int previous_marker; + CFHDDSPContext dsp; } CFHDContext;