PR #25602 opened by Marvin Scholz (ePirat) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25602 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25602.patch
In `av_encryption_init_info_alloc()`, the size variables were assigned to the struct before checking whether the corresponding allocations succeeded. In case of `info->key_ids`, if alloc failed, it would still write `num_key_ids` into the struct before doing the call check and call `av_encryption_init_info_free`, which due to the non-zero `num_key_ids` would try to iterate over `key_ids`, dereferencing a `NULL` pointer. To fix that, assign the size and count fields only after verifying that the allocations succeeded, so the struct remains consistent even for the error cleanup path. Also make the test iterate instead of using recursion, followin up to 969c7eb091. >From 273dfbb17df50c93f79313b48f0dc605455ca1aa Mon Sep 17 00:00:00 2001 From: Alex Vasilenko <[email protected]> Date: Fri, 23 Oct 2026 02:02:02 +0000 Subject: [PATCH 1/2] avutil/tests/encryption_info: make compare_encryption_init_info iterative Follow-up to 969c7eb09198, which replaced recursion with iteration in av_encryption_init_info_free() to avoid stack exhaustion on long init info lists. Replace the recursive call in compare_encryption_init_info() with an iterative loop as well so tests can compare deep lists without overflowing the stack. Signed-off-by: Marvin Scholz <[email protected]> --- libavutil/tests/encryption_info.c | 35 ++++++++++++++++--------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/libavutil/tests/encryption_info.c b/libavutil/tests/encryption_info.c index d8f0187ef97..84287a203a6 100644 --- a/libavutil/tests/encryption_info.c +++ b/libavutil/tests/encryption_info.c @@ -47,28 +47,29 @@ static int compare_encryption_info(const AVEncryptionInfo *a, const AVEncryption } static int compare_encryption_init_info(const AVEncryptionInitInfo *a, const AVEncryptionInitInfo *b) { - if (!a || !b || a->system_id_size != b->system_id_size || - a->num_key_ids != b->num_key_ids || a->key_id_size != b->key_id_size || - a->data_size != b->data_size) + if (!a || !b) return 1; - if (memcmp(a->system_id, b->system_id, a->system_id_size) != 0 || - memcmp(a->data, b->data, a->data_size) != 0) - return 1; - - for (uint32_t i = 0; i < a->num_key_ids; i++) { - if (memcmp(a->key_ids[i], b->key_ids[i], a->key_id_size) != 0) + while (a && b) { + if (a->system_id_size != b->system_id_size || + a->num_key_ids != b->num_key_ids || a->key_id_size != b->key_id_size || + a->data_size != b->data_size) return 1; + + if (memcmp(a->system_id, b->system_id, a->system_id_size) != 0 || + memcmp(a->data, b->data, a->data_size) != 0) + return 1; + + for (uint32_t i = 0; i < a->num_key_ids; i++) { + if (memcmp(a->key_ids[i], b->key_ids[i], a->key_id_size) != 0) + return 1; + } + + a = a->next; + b = b->next; } - if (a->next || b->next) { - if (!a->next || !b->next) - return 1; - if (compare_encryption_init_info(a->next, b->next) != 0) - return 1; - } - - return 0; + return a != b; } static void run_encryption_info_test(void) -- 2.54.0 >From b223973bb76440b30d2f8356e54fcec966337f26 Mon Sep 17 00:00:00 2001 From: Marvin Scholz <[email protected]> Date: Thu, 29 Oct 2026 23:40:45 +0000 Subject: [PATCH 2/2] avutil/encryption_info: set size fields only after allocation checks In av_encryption_init_info_alloc(), the size variables were assigned to the struct before checking whether the corresponding allocations succeeded. In case of info->key_ids, if alloc failed, it would still write num_key_ids into the struct before doing the call check and call av_encryption_init_info_free, which due to the non-zero num_key_ids would try to iterate over key_ids, dereferencing a NULL pointer. To fix that, assign the size and count fields only after verifying that the allocations succeeded, so the struct remains consistent even for the error cleanup path. Signed-off-by: Marvin Scholz <[email protected]> --- libavutil/encryption_info.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libavutil/encryption_info.c b/libavutil/encryption_info.c index 9643840157f..0b8843b3db6 100644 --- a/libavutil/encryption_info.c +++ b/libavutil/encryption_info.c @@ -190,12 +190,8 @@ AVEncryptionInitInfo *av_encryption_init_info_alloc( return NULL; info->system_id = av_mallocz(system_id_size); - info->system_id_size = system_id_size; info->key_ids = key_id_size ? av_calloc(num_key_ids, sizeof(*info->key_ids)) : NULL; - info->num_key_ids = num_key_ids; - info->key_id_size = key_id_size; info->data = av_mallocz(data_size); - info->data_size = data_size; // Allow pointers to be NULL if the size is 0. if ((!info->system_id && system_id_size) || (!info->data && data_size) || @@ -204,6 +200,11 @@ AVEncryptionInitInfo *av_encryption_init_info_alloc( return NULL; } + info->system_id_size = system_id_size; + info->num_key_ids = num_key_ids; + info->key_id_size = key_id_size; + info->data_size = data_size; + if (key_id_size) { for (i = 0; i < num_key_ids; i++) { info->key_ids[i] = av_mallocz(key_id_size); -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
