Commit 6b0b15b0d6 for ffmpeg
commit 6b0b15b0d6d0344b295395fccd0db642049df20e
Author: Michael Niedermayer <michael@niedermayer.cc>
Date: Sun Oct 25 05:48:24 2026 +0100
avcodec/dovi_rpuenc: reject metadata with more extension blocks than the cache holds
Fixes: EMtBgkYsAzTJ/testcase/dovi_ext_overflow.c
Fixes: EMtBgkYsAzTJ
Fixes: out of array write
Out of array write Replicated through API with ASAN
Found during the review of PR 25408.
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c
index bdda95f991..2e567ad751 100644
--- a/libavcodec/dovi_rpuenc.c
+++ b/libavcodec/dovi_rpuenc.c
@@ -651,7 +651,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata,
const AVDOVIColorMetadata *color;
int vdr_dm_metadata_present, vdr_rpu_id, use_prev_vdr_rpu, profile,
buffer_size, rpu_size, pad, zero_run, dm_compression;
- int num_ext_blocks_v1, num_ext_blocks_v2;
+ int num_ext_blocks_v1, num_ext_blocks_v2, num_static, num_dynamic;
int dv_md_compression = s->cfg.dv_md_compression;
uint32_t crc;
uint8_t *dst;
@@ -744,10 +744,15 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata,
}
num_ext_blocks_v1 = num_ext_blocks_v2 = 0;
+ num_static = num_dynamic = 0;
for (int i = 0; i < metadata->num_ext_blocks; i++) {
const AVDOVIDmData *dm = av_dovi_get_ext(metadata, i);
- if (dm_compression && ff_dovi_rpu_extension_is_static(dm->level))
- continue;
+ if (ff_dovi_rpu_extension_is_static(dm->level)) {
+ num_static++;
+ if (dm_compression)
+ continue;
+ } else
+ num_dynamic++;
switch (dm->level) {
case 1:
@@ -772,6 +777,12 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata,
return AVERROR_INVALIDDATA;
}
}
+ if (num_static > FF_ARRAY_ELEMS(s->ext_blocks->dm_static) ||
+ num_dynamic > FF_ARRAY_ELEMS(s->ext_blocks->dm_dynamic)) {
+ av_log(s->logctx, AV_LOG_ERROR, "Too many ext blocks: %d static, %d dynamic\n",
+ num_static, num_dynamic);
+ return AVERROR_INVALIDDATA;
+ }
buffer_size = 12 /* vdr seq info */ + 5 /* CRC32 + terminator */;
buffer_size += num_ext_blocks_v1 * 13;