[vlc-commits] input: always sanitize filenames from formatted meta-data

Rémi Denis-Courmont git at videolan.org
Tue May 17 19:58:30 CEST 2016


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue May 17 20:29:38 2016 +0300| [e1dc29e2461baa9d863245562341cb65a0205679] | committer: Rémi Denis-Courmont

input: always sanitize filenames from formatted meta-data

The input item name can contain special characters. It is not too hard
to imagine how this could be exploited.

path_sanitize() is inadequate as it cannot differentiate special
characters that are part of the trusted format string from special
characters that came from expanding the input item name. Instead,
filename_sanitize() must be used to eliminate all special characters.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=e1dc29e2461baa9d863245562341cb65a0205679
---

 src/input/input.c           |   39 +++++++------------
 src/libvlc-module.c         |    4 +-
 src/video_output/snapshot.c |   91 +++++++++++++++++++------------------------
 3 files changed, 56 insertions(+), 78 deletions(-)

diff --git a/src/input/input.c b/src/input/input.c
index bea3d51..75d5360 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -2889,34 +2889,21 @@ void input_UpdateStatistic( input_thread_t *p_input,
 
 /**/
 /* TODO FIXME nearly the same logic that snapshot code */
-char *input_CreateFilename( input_thread_t *input, const char *psz_path, const char *psz_prefix, const char *psz_extension )
+char *input_CreateFilename(input_thread_t *input, const char *dir,
+                           const char *filenamefmt, const char *ext)
 {
-    char *psz_file;
-    DIR *path;
-
-    path = vlc_opendir( psz_path );
-    if( path )
-    {
-        closedir( path );
+    char *path;
+    char *filename = str_format(input, filenamefmt);
+    if (unlikely(filename == NULL))
+        return NULL;
 
-        char *psz_tmp = str_format( input, psz_prefix );
-        if( !psz_tmp )
-            return NULL;
+    filename_sanitize(filename);
 
-        filename_sanitize( psz_tmp );
+    if (((ext != NULL)
+            ? asprintf(&path, "%s"DIR_SEP"%s.%s", dir, filename, ext)
+            : asprintf(&path, "%s"DIR_SEP"%s", dir, filename)) < 0)
+        path = NULL;
 
-        if( asprintf( &psz_file, "%s"DIR_SEP"%s%s%s",
-                      psz_path, psz_tmp,
-                      psz_extension ? "." : "",
-                      psz_extension ? psz_extension : "" ) < 0 )
-            psz_file = NULL;
-        free( psz_tmp );
-        return psz_file;
-    }
-    else
-    {
-        psz_file = str_format( input, psz_path );
-        path_sanitize( psz_file );
-        return psz_file;
-    }
+    free(filename);
+    return path;
 }
diff --git a/src/libvlc-module.c b/src/libvlc-module.c
index 9cd6daf..74fc7e5 100644
--- a/src/libvlc-module.c
+++ b/src/libvlc-module.c
@@ -652,9 +652,9 @@ static const char *const ppsz_prefres[] = {
     "the form \"{name=bookmark-name,time=optional-time-offset," \
     "bytes=optional-byte-offset},{...}\"")
 
-#define INPUT_RECORD_PATH_TEXT N_("Record directory or filename")
+#define INPUT_RECORD_PATH_TEXT N_("Record directory")
 #define INPUT_RECORD_PATH_LONGTEXT N_( \
-    "Directory or filename where the records will be stored" )
+    "Directory where the records will be stored" )
 
 #define INPUT_RECORD_NATIVE_TEXT N_("Prefer native stream recording")
 #define INPUT_RECORD_NATIVE_LONGTEXT N_( \
diff --git a/src/video_output/snapshot.c b/src/video_output/snapshot.c
index a37cdf1..87b05db 100644
--- a/src/video_output/snapshot.c
+++ b/src/video_output/snapshot.c
@@ -145,62 +145,53 @@ int vout_snapshot_SaveImage(char **name, int *sequential,
 {
     /* */
     char *filename;
-    DIR *pathdir = vlc_opendir(cfg->path);
     input_thread_t *input = (input_thread_t*)p_vout->p->input;
-    if (pathdir != NULL) {
-        /* The use specified a directory path */
-        closedir(pathdir);
-
-        /* */
-        char *prefix = NULL;
-        if (cfg->prefix_fmt)
-            prefix = str_format(input, cfg->prefix_fmt);
-        if (prefix)
-            filename_sanitize(prefix);
-        else {
-            prefix = strdup("vlcsnap-");
-            if (!prefix)
-                goto error;
-        }
 
-        if (cfg->is_sequential) {
-            for (int num = cfg->sequence; ; num++) {
-                struct stat st;
-
-                if (asprintf(&filename, "%s" DIR_SEP "%s%05d.%s",
-                             cfg->path, prefix, num, cfg->format) < 0) {
-                    free(prefix);
-                    goto error;
-                }
-                if (vlc_stat(filename, &st)) {
-                    *sequential = num;
-                    break;
-                }
-                free(filename);
+    /* */
+    char *prefix = NULL;
+    if (cfg->prefix_fmt)
+        prefix = str_format(input, cfg->prefix_fmt);
+    if (prefix)
+        filename_sanitize(prefix);
+    else {
+        prefix = strdup("vlcsnap-");
+        if (prefix == NULL)
+            goto error;
+    }
+
+    if (cfg->is_sequential) {
+        for (int num = cfg->sequence; ; num++) {
+            struct stat st;
+
+            if (asprintf(&filename, "%s" DIR_SEP "%s%05d.%s",
+                         cfg->path, prefix, num, cfg->format) < 0) {
+                free(prefix);
+                goto error;
+            }
+            if (vlc_stat(filename, &st)) {
+                *sequential = num;
+                break;
             }
-        } else {
-            struct timespec ts;
-            struct tm curtime;
-            char buffer[128];
-
-            timespec_get(&ts, TIME_UTC);
-            if (localtime_r(&ts.tv_sec, &curtime) == NULL)
-                gmtime_r(&ts.tv_sec, &curtime);
-            if (strftime(buffer, sizeof(buffer), "%Y-%m-%d-%Hh%Mm%Ss",
-                         &curtime) == 0)
-                strcpy(buffer, "error");
-
-            if (asprintf(&filename, "%s" DIR_SEP "%s%s%03lu.%s",
-                         cfg->path, prefix, buffer, ts.tv_nsec / 1000000,
-                         cfg->format) < 0)
-                filename = NULL;
+            free(filename);
         }
-        free(prefix);
     } else {
-        /* The user specified a full path name (including file name) */
-        filename = str_format(input, cfg->path);
-        path_sanitize(filename);
+        struct timespec ts;
+        struct tm curtime;
+        char buffer[128];
+
+        timespec_get(&ts, TIME_UTC);
+        if (localtime_r(&ts.tv_sec, &curtime) == NULL)
+            gmtime_r(&ts.tv_sec, &curtime);
+        if (strftime(buffer, sizeof(buffer), "%Y-%m-%d-%Hh%Mm%Ss",
+                     &curtime) == 0)
+            strcpy(buffer, "error");
+
+        if (asprintf(&filename, "%s" DIR_SEP "%s%s%03lu.%s",
+                     cfg->path, prefix, buffer, ts.tv_nsec / 1000000,
+                     cfg->format) < 0)
+            filename = NULL;
     }
+    free(prefix);
 
     if (!filename)
         goto error;



More information about the vlc-commits mailing list