This is an automated email from the git hooks/post-receive script.
Git pushed a commit to branch master
in repository ffmpeg.
The following commit(s) were added to refs/heads/master by this push:
new 4945e33e98 avformat/dashdec: bound manifest reloads and fragment-open
retries
4945e33e98 is described below
commit 4945e33e987ea17e4bc0571e3e5ffde606ac5961
Author: Michael Niedermayer <[email protected]>
AuthorDate: Thu May 21 21:59:01 2026 +0200
Commit: michaelni <[email protected]>
CommitDate: Mon May 25 22:35:21 2026 +0000
avformat/dashdec: bound manifest reloads and fragment-open retries
Mirror the HLS demuxer's max_reload pattern
Reported as a DoS finding by Xueqing. Verified with the supplied PoC
server: a 30s ffmpeg run that previously generated ~10000 requests
without termination now exits in ~100ms after exactly max_reload
fragment-open failures.
---
libavformat/dashdec.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
index cac2250634..bed82fcf45 100644
--- a/libavformat/dashdec.c
+++ b/libavformat/dashdec.c
@@ -113,6 +113,7 @@ struct representation {
int64_t cur_seg_offset;
int64_t cur_seg_size;
struct fragment *cur_seg;
+ int n_open_failures; /* consecutive open_input failures since
last good read */
/* Currently active Media Initialization Section */
struct fragment *init_section;
@@ -157,6 +158,7 @@ typedef struct DASHContext {
char *allowed_extensions;
AVDictionary *avio_opts;
int max_url_size;
+ int max_reload;
char *cenc_decryption_key;
char *cenc_decryption_keys;
@@ -1649,6 +1651,7 @@ static struct fragment *get_current_fragment(struct
representation *pls)
struct fragment *seg = NULL;
struct fragment *seg_ptr = NULL;
DASHContext *c = pls->parent->priv_data;
+ int reload_count = 0;
while (( !ff_check_interrupt(c->interrupt_callback)&& pls->n_fragments >
0)) {
if (pls->cur_seq_no < pls->n_fragments) {
@@ -1666,6 +1669,12 @@ static struct fragment *get_current_fragment(struct
representation *pls)
seg->url_offset = seg_ptr->url_offset;
return seg;
} else if (c->is_live) {
+ if (reload_count++ >= c->max_reload) {
+ av_log(pls->parent, AV_LOG_ERROR,
+ "Reached max manifest reloads (%d) at seq %"PRId64"\n",
+ c->max_reload, pls->cur_seq_no);
+ return NULL;
+ }
refresh_manifest(pls->parent);
} else {
break;
@@ -1856,9 +1865,17 @@ restart:
goto end;
}
av_log(v->parent, AV_LOG_WARNING, "Failed to open fragment of
playlist\n");
+ if (++v->n_open_failures > c->max_reload) {
+ av_log(v->parent, AV_LOG_ERROR,
+ "Reached max consecutive fragment open failures (%d),
giving up\n",
+ c->max_reload);
+ ret = AVERROR_EOF;
+ goto end;
+ }
v->cur_seq_no++;
goto restart;
}
+ v->n_open_failures = 0;
}
if (v->init_sec_buf_read_offset < v->init_sec_data_len) {
@@ -2505,6 +2522,8 @@ static const AVOption dash_options[] = {
INT_MIN, INT_MAX, FLAGS},
{ "cenc_decryption_key", "Media default decryption key (hex)",
OFFSET(cenc_decryption_key), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN,
INT_MAX, .flags = FLAGS },
{ "cenc_decryption_keys", "Media decryption keys by KID (hex)",
OFFSET(cenc_decryption_keys), AV_OPT_TYPE_STRING, {.str = NULL}, INT_MIN,
INT_MAX, .flags = FLAGS },
+ { "max_reload", "Maximum number of manifest reloads in
get_current_fragment() before giving up",
+ OFFSET(max_reload), AV_OPT_TYPE_INT, { .i64 = 100 }, 0, INT_MAX, FLAGS
},
{NULL}
};
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]