From patchwork Wed Nov 25 19:33:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Sebastian_Dr=C3=B6ge?= X-Patchwork-Id: 24032 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 D5C4344936F for ; Wed, 25 Nov 2020 21:34:09 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A913468BB2A; Wed, 25 Nov 2020 21:34:09 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from coaxion.net (coaxion.net [163.172.61.46]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id CF88068AD9D for ; Wed, 25 Nov 2020 21:34:02 +0200 (EET) From: =?utf-8?q?Sebastian_Dr=C3=B6ge?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=coaxion.net; s=default; t=1606332842; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Ht7KsloN5kphvVAOAPlhbZp6HRmrKcatfFt/RWPZf5s=; b=MqYyyF7rZb38F1OMxdlwGe+TZw5BLjXiTTmqrupwP8V6LGFqYuFzHKEGVagNlRYktdpie8 HsJ6nMvP+tKch68AS7gyifG3BUbPID7OmVs570yw0zhYiQkGFz04/Cjn8vsgbIFuSNngVu zYGivZNvmrF/1+89AcIQfe1PfPeE34qtj6Bggux518YLNUH1pU/QrIgMGZBxJRxhAkUKEg dHxJPbGzH4aLoJcFZTClCnjmweNRrp8m0PsFTBtTQkXTWLrNPivd36PevPtT3x/tBFX+PF +syDMd2BH+s6SxY+/69LB/29RDQO6Cmke7Q/BannSh/hL0q9ZAuT/Yp7FONoAA== To: ffmpeg-devel@ffmpeg.org Date: Wed, 25 Nov 2020 21:33:59 +0200 Message-Id: <20201125193359.1152240-1-slomo@coaxion.net> X-Mailer: git-send-email 2.29.2 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avdevice/decklink_dec: Handle time code data presence in CDP packets 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: =?utf-8?q?Sebastian_Dr=C3=B6ge?= Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Sebastian Dröge Instead of failing to parse such CDP packets, simply skip over the time code data and read the CC data following it. Also add some more length checks in related to this and the existing parsing code to prevent reading out of bounds memory. --- libavdevice/decklink_dec.cpp | 60 ++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 2e41b587e8..2194e84226 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -329,18 +329,30 @@ static uint8_t* teletext_data_unit_from_ancillary_packet(uint16_t *py, uint16_t static uint8_t *vanc_to_cc(AVFormatContext *avctx, uint16_t *buf, size_t words, unsigned &cc_count) { - size_t i, len = (buf[5] & 0xff) + 6 + 1; + size_t i, len; uint8_t cdp_sum, rate; uint16_t hdr, ftr; + uint8_t flags; uint8_t *cc; - uint16_t *cdp = &buf[6]; // CDP follows + uint16_t *cdp; + + /* validity of this length is already checked by the caller */ + len = (buf[5] & 0xff) + 6 + 1; + + cdp = &buf[6]; // CDP follows + len -= 7; // remove VANC header and checksum + + /* 7 bytes CDP header, 4 bytes CDP footer */ + if (len < 7 + 4) { + av_log(avctx, AV_LOG_WARNING, "Invalid CDP packet length %zu < %d\n", len, 7 + 4); + return NULL; + } + if (cdp[0] != 0x96 || cdp[1] != 0x69) { av_log(avctx, AV_LOG_WARNING, "Invalid CDP header 0x%.2x 0x%.2x\n", cdp[0], cdp[1]); return NULL; } - len -= 7; // remove VANC header and checksum - if (cdp[2] != len) { av_log(avctx, AV_LOG_WARNING, "CDP len %d != %zu\n", cdp[2], len); return NULL; @@ -366,26 +378,48 @@ static uint8_t *vanc_to_cc(AVFormatContext *avctx, uint16_t *buf, size_t words, return NULL; } - if (!(cdp[4] & 0x43)) /* ccdata_present | caption_service_active | reserved */ { - av_log(avctx, AV_LOG_WARNING, "CDP flags invalid (0x%.2x)\n", cdp[4]); + flags = cdp[4]; + if (!(flags & 0x43)) /* ccdata_present | caption_service_active | reserved */ { + av_log(avctx, AV_LOG_WARNING, "CDP flags invalid (0x%.2x)\n", flags); return NULL; } hdr = (cdp[5] << 8) | cdp[6]; - if (cdp[7] != 0x72) /* ccdata_id */ { + + /* skip over the CDP header parsed above */ + cdp += 7; + len -= 7; + + if ((flags & 0x80)) /* time_code_present */ { + /* time code is stored in 5 bytes, skip over them */ + if (len < 5) { + av_log(avctx, AV_LOG_WARNING, "CDP length too small for time code section\n"); + return NULL; + } + cdp += 5; + len -= 5; + } + + if (len < 2) { + av_log(avctx, AV_LOG_WARNING, "CDP length too small for CC data section\n"); + return NULL; + } + + if (cdp[0] != 0x72) /* ccdata_id */ { av_log(avctx, AV_LOG_WARNING, "Invalid ccdata_id 0x%.2x\n", cdp[7]); return NULL; } - cc_count = cdp[8]; + cc_count = cdp[1]; if (!(cc_count & 0xe0)) { av_log(avctx, AV_LOG_WARNING, "Invalid cc_count 0x%.2x\n", cc_count); return NULL; } cc_count &= 0x1f; - if ((len - 13) < cc_count * 3) { - av_log(avctx, AV_LOG_WARNING, "Invalid cc_count %d (> %zu)\n", cc_count * 3, len - 13); + /* 6 = 2 bytes for the CC data header read above and 4 bytes for the CDP footer */ + if (len < cc_count * 3 + 6) { + av_log(avctx, AV_LOG_WARNING, "Invalid cc_count %d (> %zu)\n", cc_count * 3, len - 6); return NULL; } @@ -407,9 +441,9 @@ static uint8_t *vanc_to_cc(AVFormatContext *avctx, uint16_t *buf, size_t words, } for (size_t i = 0; i < cc_count; i++) { - cc[3*i + 0] = cdp[9 + 3*i+0] /* & 3 */; - cc[3*i + 1] = cdp[9 + 3*i+1]; - cc[3*i + 2] = cdp[9 + 3*i+2]; + cc[3*i + 0] = cdp[2 + 3*i+0] /* & 3 */; + cc[3*i + 1] = cdp[2 + 3*i+1]; + cc[3*i + 2] = cdp[2 + 3*i+2]; } cc_count *= 3;