mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-06-16 04:32:47 +02:00
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 <michael@niedermayer.cc>
This commit is contained in:
committed by
michaelni
parent
82f097c825
commit
d2dd0a0a8f
+13
-2
@@ -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,18 @@ 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),
|
||||
{
|
||||
.nb_unit_types = 1,
|
||||
.unit_type.list = { HEVC_NAL_VPS },
|
||||
.content_type = CBS_CONTENT_TYPE_INTERNAL_REFS,
|
||||
.content_size = sizeof(H265RawVPS),
|
||||
.type.ref = {
|
||||
.nb_offsets = 2,
|
||||
.offsets = { offsetof(H265RawVPS, extension_data.data),
|
||||
offsetof(H265RawVPS, 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),
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user