PR #22519 opened by Huihui_Huang
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22519
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22519.patch
### Description:
`ffurl_connect()` creates a temporary dictionary (tmp_opts) when the caller
passes NULL for the options parameter (lines **211-212**):
``` c
if (!options)
options = &tmp_opts;
```
The function then inserts `protocol_whitelist` and `protocol_blacklist` entries
into this dictionary using `av_dict_set()`.
If one of these av_dict_set() calls fails after an entry has already been
inserted, the function returns immediately without freeing the temporary
dictionary (**239-242**). Since `tmp_opts` is only used internally in this
case, this may result in a memory leak on the error path.
### Fix:
Redirect error paths to a cleanup section and free tmp_opts when it is created
internally. The fix is included in this commit.
>From c809d8435efac88c88a4f7c8b26aa9459eb4e712 Mon Sep 17 00:00:00 2001
From: huanghuihui0904 <[email protected]>
Date: Mon, 16 Mar 2026 17:07:48 +0800
Subject: [PATCH] avformat: avoid potential tmp_opts leak in ffurl_connect()
When options is NULL, ffurl_connect() creates a temporary dictionary
(tmp_opts). If av_dict_set() fails after inserting entries, the function may
return without freeing this dictionary.
Ensure tmp_opts is freed on error paths.
Signed-off-by: Huihui_Huang <[email protected]>
---
libavformat/avio.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/libavformat/avio.c b/libavformat/avio.c
index c685e0ab71..3d723c1c09 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -237,9 +237,9 @@ int ffurl_connect(URLContext *uc, AVDictionary **options)
av_log(uc, AV_LOG_DEBUG, "No default whitelist set\n"); // This should
be an error once all declare a default whitelist
if ((err = av_dict_set(options, "protocol_whitelist",
uc->protocol_whitelist, 0)) < 0)
- return err;
+ goto fail;
if ((err = av_dict_set(options, "protocol_blacklist",
uc->protocol_blacklist, 0)) < 0)
- return err;
+ goto fail;
err =
uc->prot->url_open2 ? uc->prot->url_open2(uc,
@@ -252,14 +252,23 @@ int ffurl_connect(URLContext *uc, AVDictionary **options)
av_dict_set(options, "protocol_blacklist", NULL, 0);
if (err)
- return err;
+ goto fail;
uc->is_connected = 1;
/* We must be careful here as ffurl_seek() could be slow,
* for example for http */
if ((uc->flags & AVIO_FLAG_WRITE) || !strcmp(uc->prot->name, "file"))
if (!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0)
uc->is_streamed = 1;
+
+ if (options == &tmp_opts)
+ av_dict_free(&tmp_opts);
+
return 0;
+
+fail:
+ if (options == &tmp_opts)
+ av_dict_free(&tmp_opts);
+ return err;
}
int ffurl_accept(URLContext *s, URLContext **c)
--
2.52.0
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]