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]

Reply via email to