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

# Summary of changes

`av_encryption_init_info_alloc()` allocates `key_ids` only when `key_id_size`
is non-zero, but stores `num_key_ids` unconditionally. If called with
`num_key_ids > 0` and `key_id_size == 0`, it returns an object with a `NULL`
`key_ids` array and a non-zero `num_key_ids`. The consumers
`av_encryption_init_info_free()`, `av_encryption_init_info_get_side_data()`
and `av_encryption_init_info_add_side_data()` all loop over `num_key_ids`
and dereference `key_ids[i]`, causing a null pointer dereference. The values
are parsed from side data, so this can be triggered with crafted input.

Reject the `num_key_ids > 0 && key_id_size == 0` combination at allocation
time, returning `NULL` instead of an inconsistent object.

Tested by calling `av_encryption_init_info_alloc()` with both the affected
and the valid parameter combinations.


>From c55db006f51e6b951b7ddee1faf5b22f20e299a8 Mon Sep 17 00:00:00 2001
From: tangsha <[email protected]>
Date: Wed, 20 May 2026 15:02:47 +0800
Subject: [PATCH 1/5] avcodec/wavpack: Fix memory leak in
 wv_alloc_frame_context()

When av_mallocz() fails after av_realloc_array() succeeds,
the reallocated fdec pointer is leaked.
---
 libavcodec/wavpack.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 341315373f..0dd9f4258f 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -980,7 +980,11 @@ static av_cold int wv_alloc_frame_context(WavpackContext 
*c)
 
     c->fdec[c->fdec_num] = av_mallocz(sizeof(**c->fdec));
     if (!c->fdec[c->fdec_num])
+    {
+        av_free(&c->fdec);
+        c->fdec = NULL;
         return -1;
+    }
     c->fdec_num++;
     c->fdec[c->fdec_num - 1]->avctx = c->avctx;
 
-- 
2.52.0


>From a457269a6392470f408eb1115bcda8c5c9ff8381 Mon Sep 17 00:00:00 2001
From: tangsha <[email protected]>
Date: Mon, 31 Aug 2026 19:54:44 +0800
Subject: [PATCH 2/5] Revert "avcodec/wavpack: Fix memory leak in
 wv_alloc_frame_context()"

This reverts commit c55db006f51e6b951b7ddee1faf5b22f20e299a8.
---
 libavcodec/wavpack.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 0dd9f4258f..341315373f 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -980,11 +980,7 @@ static av_cold int wv_alloc_frame_context(WavpackContext 
*c)
 
     c->fdec[c->fdec_num] = av_mallocz(sizeof(**c->fdec));
     if (!c->fdec[c->fdec_num])
-    {
-        av_free(&c->fdec);
-        c->fdec = NULL;
         return -1;
-    }
     c->fdec_num++;
     c->fdec[c->fdec_num - 1]->avctx = c->avctx;
 
-- 
2.52.0


>From a1bb40919b4d1ffb3b06639726a532f33a6cf3ae Mon Sep 17 00:00:00 2001
From: tangsha <[email protected]>
Date: Wed, 20 May 2026 15:02:47 +0800
Subject: [PATCH 3/5] avcodec/wavpack: Fix memory leak in
 wv_alloc_frame_context()

When av_mallocz() fails after av_realloc_array() succeeds,
the reallocated fdec pointer is leaked.
---
 libavcodec/wavpack.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 87c2ded5e4..6f4baa0cc5 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -980,7 +980,11 @@ static av_cold int wv_alloc_frame_context(WavpackContext 
*c)
 
     c->fdec[c->fdec_num] = av_mallocz(sizeof(**c->fdec));
     if (!c->fdec[c->fdec_num])
+    {
+        av_free(&c->fdec);
+        c->fdec = NULL;
         return -1;
+    }
     c->fdec_num++;
     c->fdec[c->fdec_num - 1]->avctx = c->avctx;
 
-- 
2.52.0


>From 8e59f94f6a4b5fd6f0184dfe00a7063117c08cf9 Mon Sep 17 00:00:00 2001
From: tangsha <[email protected]>
Date: Mon, 31 Aug 2026 19:54:44 +0800
Subject: [PATCH 4/5] Revert "avcodec/wavpack: Fix memory leak in
 wv_alloc_frame_context()"

This reverts commit c55db006f51e6b951b7ddee1faf5b22f20e299a8.
---
 libavcodec/wavpack.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 6f4baa0cc5..87c2ded5e4 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -980,11 +980,7 @@ static av_cold int wv_alloc_frame_context(WavpackContext 
*c)
 
     c->fdec[c->fdec_num] = av_mallocz(sizeof(**c->fdec));
     if (!c->fdec[c->fdec_num])
-    {
-        av_free(&c->fdec);
-        c->fdec = NULL;
         return -1;
-    }
     c->fdec_num++;
     c->fdec[c->fdec_num - 1]->avctx = c->avctx;
 
-- 
2.52.0


>From e8583684870122db7ff8a59ffacf1423e774fcad Mon Sep 17 00:00:00 2001
From: tangsha <[email protected]>
Date: Mon, 31 Aug 2026 20:20:31 +0800
Subject: [PATCH 5/5] avutil/encryption_info: reject init info with zero-sized
 key IDs

av_encryption_init_info_alloc() only allocates key_ids when key_id_size is
non-zero, but stores num_key_ids regardless. If num_key_ids is non-zero and
key_id_size is 0, the returned object has a NULL key_ids array alongside a
non-zero num_key_ids. av_encryption_init_info_free(),
av_encryption_init_info_get_side_data() and
av_encryption_init_info_add_side_data() then loop over num_key_ids and
dereference key_ids[i], leading to a null pointer dereference.

Reject the num_key_ids > 0 && key_id_size == 0 combination instead of
returning an inconsistent object.

Signed-off-by: tangsha <[email protected]>
---
 libavutil/encryption_info.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavutil/encryption_info.c b/libavutil/encryption_info.c
index e4ff015b37..a3eb955d2d 100644
--- a/libavutil/encryption_info.c
+++ b/libavutil/encryption_info.c
@@ -181,6 +181,9 @@ AVEncryptionInitInfo *av_encryption_init_info_alloc(
     AVEncryptionInitInfo *info;
     uint32_t i;
 
+    if (num_key_ids && !key_id_size)
+        return NULL;
+
     info = av_mallocz(sizeof(*info));
     if (!info)
         return NULL;
-- 
2.52.0

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

Reply via email to