PR #23278 opened by michaelni
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23278
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23278.patch

H265RawVPS embedded hrd_parameters as an inline array of
HEVC_MAX_LAYER_SETS (1024) H265RawHRDParameters, making the structure
roughly 7.9 MB. CBS allocates the whole content structure for every VPS
NAL unit before parsing it, so a packet consisting of many tiny VPS NALs
forces gigabytes of allocations and triggers an out-of-memory condition.

Allocate hrd_parameters separately, sized to vps_num_hrd_parameters,
backed by an AVBufferRef registered as a second internal reference
offset on the VPS unit type. This shrinks the resident structure to tens
of kilobytes and bounds the hrd_parameters allocation by the amount that
is actually parsed.

Fixes: 
472754452/clusterfuzz-testcase-minimized-ffmpeg_BSF_HEVC_METADATA_fuzzer-6379024978083840
Found-by: continuous fuzzing process 
https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <[email protected]>


>From 6284a60781186f3ea9cd603da4c3c724e84868ca Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Sat, 30 May 2026 05:12:22 +0200
Subject: [PATCH] avcodec/cbs_h265: allocate VPS hrd_parameters dynamically

H265RawVPS embedded hrd_parameters as an inline array of
HEVC_MAX_LAYER_SETS (1024) H265RawHRDParameters, making the structure
roughly 7.9 MB. CBS allocates the whole content structure for every VPS
NAL unit before parsing it, so a packet consisting of many tiny VPS NALs
forces gigabytes of allocations and triggers an out-of-memory condition.

Allocate hrd_parameters separately, sized to vps_num_hrd_parameters,
backed by an AVBufferRef registered as a second internal reference
offset on the VPS unit type. This shrinks the resident structure to tens
of kilobytes and bounds the hrd_parameters allocation by the amount that
is actually parsed.

Fixes: 
472754452/clusterfuzz-testcase-minimized-ffmpeg_BSF_HEVC_METADATA_fuzzer-6379024978083840
Found-by: continuous fuzzing process 
https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <[email protected]>
---
 libavcodec/cbs_h265.c                 |  5 +++--
 libavcodec/cbs_h265.h                 |  3 ++-
 libavcodec/cbs_h265_syntax_template.c |  4 ++++
 libavcodec/cbs_internal.h             | 10 ++++++++++
 4 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/libavcodec/cbs_h265.c b/libavcodec/cbs_h265.c
index 21df609d08..5f46cda1f6 100644
--- a/libavcodec/cbs_h265.c
+++ b/libavcodec/cbs_h265.c
@@ -142,7 +142,7 @@ static int FUNC_H265(name) args
                                         AV_INPUT_BUFFER_PADDING_SIZE); \
         if (!name ## _ref) \
             return AVERROR(ENOMEM); \
-        name = name ## _ref->data; \
+        name = (void *)name ## _ref->data; \
     } while (0)
 
 #define FUNC(name) FUNC_H265(name)
@@ -715,7 +715,8 @@ static void cbs_h265_free_sei(AVRefStructOpaque unused, 
void *content)
 }
 
 static CodedBitstreamUnitTypeDescriptor cbs_h265_unit_types[] = {
-    CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_VPS, H265RawVPS, extension_data.data),
+    CBS_UNIT_TYPE_INTERNAL_REF_2(HEVC_NAL_VPS, H265RawVPS, extension_data.data,
+                                 hrd_parameters),
     CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_SPS, H265RawSPS, extension_data.data),
     CBS_UNIT_TYPE_INTERNAL_REF(HEVC_NAL_PPS, H265RawPPS, extension_data.data),
 
diff --git a/libavcodec/cbs_h265.h b/libavcodec/cbs_h265.h
index bb7a29c2e5..cd84b7b594 100644
--- a/libavcodec/cbs_h265.h
+++ b/libavcodec/cbs_h265.h
@@ -211,7 +211,8 @@ typedef struct H265RawVPS {
     uint16_t vps_num_hrd_parameters;
     uint16_t hrd_layer_set_idx[HEVC_MAX_LAYER_SETS];
     uint8_t cprms_present_flag[HEVC_MAX_LAYER_SETS];
-    H265RawHRDParameters hrd_parameters[HEVC_MAX_LAYER_SETS];
+    H265RawHRDParameters *hrd_parameters;
+    AVBufferRef          *hrd_parameters_ref;
 
     uint8_t vps_extension_flag;
     H265RawExtensionData extension_data;
diff --git a/libavcodec/cbs_h265_syntax_template.c 
b/libavcodec/cbs_h265_syntax_template.c
index 2842c40585..c97b7ed361 100644
--- a/libavcodec/cbs_h265_syntax_template.c
+++ b/libavcodec/cbs_h265_syntax_template.c
@@ -489,6 +489,10 @@ static int FUNC(vps)(CodedBitstreamContext *ctx, RWContext 
*rw,
         if (current->vps_poc_proportional_to_timing_flag)
             ue(vps_num_ticks_poc_diff_one_minus1, 0, UINT32_MAX - 1);
         ue(vps_num_hrd_parameters, 0, current->vps_num_layer_sets_minus1 + 1);
+        if (current->vps_num_hrd_parameters > 0)
+            allocate(current->hrd_parameters,
+                     current->vps_num_hrd_parameters *
+                     sizeof(*current->hrd_parameters));
         for (i = 0; i < current->vps_num_hrd_parameters; i++) {
             ues(hrd_layer_set_idx[i],
                 current->vps_base_layer_internal_flag ? 0 : 1,
diff --git a/libavcodec/cbs_internal.h b/libavcodec/cbs_internal.h
index 2af8075f78..f872efea74 100644
--- a/libavcodec/cbs_internal.h
+++ b/libavcodec/cbs_internal.h
@@ -366,6 +366,16 @@ int CBS_FUNC(write_signed)(CodedBitstreamContext *ctx, 
PutBitContext *pbc,
 #define CBS_UNIT_TYPE_INTERNAL_REF(type, structure, ref_field) \
     CBS_UNIT_TYPES_INTERNAL_REF((type), structure, ref_field)
 
+#define CBS_UNIT_TYPE_INTERNAL_REF_2(type_, structure, ref_field0, ref_field1) 
{ \
+        .nb_unit_types  = 1, \
+        .unit_type.list = { type_ }, \
+        .content_type   = CBS_CONTENT_TYPE_INTERNAL_REFS, \
+        .content_size   = sizeof(structure), \
+        .type.ref       = { .nb_offsets = 2, \
+                            .offsets    = { offsetof(structure, ref_field0), \
+                                            offsetof(structure, ref_field1) } 
}, \
+    }
+
 #define CBS_UNIT_RANGE_INTERNAL_REF(range_start, range_end, structure, 
ref_field) { \
         .nb_unit_types         = CBS_UNIT_TYPE_RANGE, \
         .unit_type.range.start = range_start, \
-- 
2.52.0

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

Reply via email to