PR #22448 opened by James Almer (jamrial)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22448
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22448.patch

Based on 248b481c337d917e0fece9555ae59b5375c725c6


>From fcf4b698840107db4a24b642c72c605d8d17ef25 Mon Sep 17 00:00:00 2001
From: James Almer <[email protected]>
Date: Sun, 8 Mar 2026 21:07:55 -0300
Subject: [PATCH] avcodec/lcevc_parser: Check that block_size is not negative

Based on 248b481c337d917e0fece9555ae59b5375c725c6

Signed-off-by: James Almer <[email protected]>
---
 libavcodec/bsf/extract_extradata.c | 17 +------------
 libavcodec/lcevc_parse.h           | 38 ++++++++++++++++++++++++++++++
 libavcodec/lcevc_parser.c          | 22 ++++-------------
 3 files changed, 44 insertions(+), 33 deletions(-)
 create mode 100644 libavcodec/lcevc_parse.h

diff --git a/libavcodec/bsf/extract_extradata.c 
b/libavcodec/bsf/extract_extradata.c
index 08293ea7e1..51879b0f85 100644
--- a/libavcodec/bsf/extract_extradata.c
+++ b/libavcodec/bsf/extract_extradata.c
@@ -30,6 +30,7 @@
 #include "h2645_parse.h"
 #include "h264.h"
 #include "lcevc.h"
+#include "lcevc_parse.h"
 #include "startcode.h"
 #include "vc1_common.h"
 #include "vvc.h"
@@ -268,22 +269,6 @@ static int extract_extradata_h2645(AVBSFContext *ctx, 
AVPacket *pkt,
     return 0;
 }
 
-static inline uint64_t get_mb(GetBitContext *s) {
-    int more, i = 0;
-    uint64_t mb = 0;
-
-    do {
-        int byte = get_bits(s, 8);
-        unsigned bits = byte & 0x7f;
-        more = byte & 0x80;
-        mb = (mb << 7) | bits;
-        if (++i == 10)
-            break;
-    } while (more);
-
-    return mb;
-}
-
 /**
  * Rewrite the NALu stripping the unneeded blocks.
  * Given that length fields coded inside the NALu are not aware of any 
emulation_3bytes
diff --git a/libavcodec/lcevc_parse.h b/libavcodec/lcevc_parse.h
new file mode 100644
index 0000000000..7e1f0ffd0d
--- /dev/null
+++ b/libavcodec/lcevc_parse.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_LCEVC_PARSE_H
+#define AVCODEC_LCEVC_PARSE_H
+
+static inline uint64_t get_mb(GetBitContext *s) {
+    int more, i = 0;
+    uint64_t mb = 0;
+
+    do {
+        int byte = get_bits(s, 8);
+        unsigned bits = byte & 0x7f;
+        more = byte & 0x80;
+        mb = (mb << 7) | bits;
+        if (++i == 10)
+            break;
+    } while (more);
+
+    return mb;
+}
+
+#endif /* AVCODEC_LCEVC_PARSE_H */
diff --git a/libavcodec/lcevc_parser.c b/libavcodec/lcevc_parser.c
index 77888a3efc..2ba5ba3205 100644
--- a/libavcodec/lcevc_parser.c
+++ b/libavcodec/lcevc_parser.c
@@ -100,22 +100,6 @@ static const struct {
     { 7680, 4800 },
 };
 
-static inline uint64_t get_mb(GetBitContext *s) {
-    int more, i = 0;
-    uint64_t mb = 0;
-
-    do {
-        int byte = get_bits(s, 8);
-        unsigned bits = byte & 0x7f;
-        more = byte & 0x80;
-        mb = (mb << 7) | bits;
-        if (++i == 10)
-            break;
-    } while (more);
-
-    return mb;
-}
-
 static int parse_nal_unit(AVCodecParserContext *s, AVCodecContext *avctx,
                           const H2645NAL *nal)
 {
@@ -125,7 +109,8 @@ static int parse_nal_unit(AVCodecParserContext *s, 
AVCodecContext *avctx,
 
     while (bytestream2_get_bytes_left(&gbc) > 1) {
         GetBitContext gb;
-        int payload_size_type, payload_type, payload_size;
+        uint64_t payload_size;
+        int payload_size_type, payload_type;
         int block_size;
 
         init_get_bits8(&gb, gbc.buffer, bytestream2_get_bytes_left(&gbc));
@@ -138,6 +123,9 @@ static int parse_nal_unit(AVCodecParserContext *s, 
AVCodecContext *avctx,
         if (payload_size_type == 7)
             payload_size = get_mb(&gb);
 
+        if (payload_size > INT_MAX - (get_bits_count(&gb) >> 3))
+            return AVERROR_INVALIDDATA;
+
         block_size = payload_size + (get_bits_count(&gb) >> 3);
         if (block_size >= bytestream2_get_bytes_left(&gbc))
             return AVERROR_INVALIDDATA;
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to