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 1e7d7c4f52 fftools/ffmpeg_demux: Check metadata provided filename
1e7d7c4f52 is described below
commit 1e7d7c4f5203a5badc63de82747b5abb1e56b5a0
Author: Michael Niedermayer <[email protected]>
AuthorDate: Thu Feb 19 18:14:28 2026 +0100
Commit: Michael Niedermayer <[email protected]>
CommitDate: Sat Mar 7 11:51:39 2026 +0100
fftools/ffmpeg_demux: Check metadata provided filename
Fixes: path traversal with -dump_attachment:t
Fixes: malicious.mkv
Based on code from libavformat/concatdec.c
This will be factored out possibly into libavutil once there is agreement
on the API
Found-by: Shangzhi Xu <[email protected]>
Signed-off-by: Michael Niedermayer <[email protected]>
---
fftools/ffmpeg_demux.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 56 insertions(+), 1 deletion(-)
diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index c8d8a7e044..7c708ff0f3 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -1748,6 +1748,56 @@ static int istg_add(const OptionsContext *o, Demuxer *d,
AVStreamGroup *stg)
return 0;
}
+static int is_windows_reserved_device_name(const char *f)
+{
+#if HAVE_DOS_PATHS
+ for (const char *p = f; p && *p; ) {
+ char stem[6], *s;
+ av_strlcpy(stem, p, sizeof(stem));
+ if ((s = strchr(stem, '.')))
+ *s = 0;
+ if ((s = strpbrk(stem, "123456789")))
+ *s = '1';
+
+ if( !av_strcasecmp(stem, "AUX") ||
+ !av_strcasecmp(stem, "CON") ||
+ !av_strcasecmp(stem, "NUL") ||
+ !av_strcasecmp(stem, "PRN") ||
+ !av_strcasecmp(stem, "COM1") ||
+ !av_strcasecmp(stem, "LPT1")
+ )
+ return 1;
+
+ p = strchr(p, '/');
+ if (p)
+ p++;
+ }
+#endif
+ return 0;
+}
+
+static int safe_filename(const char *f, int allow_subdir)
+{
+ const char *start = f;
+
+ if (!*f || is_windows_reserved_device_name(f))
+ return 0;
+
+ for (; *f; f++) {
+ /* A-Za-z0-9_- */
+ if (!((unsigned)((*f | 32) - 'a') < 26 ||
+ (unsigned)(*f - '0') < 10 || *f == '_' || *f == '-')) {
+ if (f == start)
+ return 0;
+ else if (allow_subdir && *f == '/')
+ start = f + 1;
+ else if (*f != '.')
+ return 0;
+ }
+ }
+ return 1;
+}
+
static int dump_attachment(InputStream *ist, const char *filename)
{
AVStream *st = ist->st;
@@ -1759,8 +1809,13 @@ static int dump_attachment(InputStream *ist, const char
*filename)
av_log(ist, AV_LOG_WARNING, "No extradata to dump.\n");
return 0;
}
- if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
+ if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0))) {
filename = e->value;
+ if (!safe_filename(filename, 0)) {
+ av_log(ist, AV_LOG_ERROR, "Filename %s is unsafe\n", filename);
+ return AVERROR(EINVAL);
+ }
+ }
if (!*filename) {
av_log(ist, AV_LOG_FATAL, "No filename specified and no 'filename'
tag");
return AVERROR(EINVAL);
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]