]> wimlib.net Git - wimlib/blobdiff - src/dentry.c
decompress_common: move temp space for building decode table to heap
[wimlib] / src / dentry.c
index 4501525dcd0d70a2b121d00a6e64d60ba31fdd99..dac85c35c2cd6ce593f5cf45e6ff292f3ed941dc 100644 (file)
@@ -484,7 +484,6 @@ int
 calculate_dentry_full_path(struct wim_dentry *dentry)
 {
        size_t ulen;
-       size_t dummy;
        const struct wim_dentry *d;
 
        if (dentry->d_full_path)
@@ -513,7 +512,7 @@ calculate_dentry_full_path(struct wim_dentry *dentry)
        wimlib_assert(p == ubuf);
 
        return utf16le_to_tstr(ubuf, ulen * sizeof(utf16lechar),
-                              &dentry->d_full_path, &dummy);
+                              &dentry->d_full_path, NULL);
 }
 
 /*
@@ -1532,7 +1531,6 @@ err_free_dentry:
        return ret;
 }
 
-/* Is the dentry named "." or ".." ?  */
 static bool
 dentry_is_dot_or_dotdot(const struct wim_dentry *dentry)
 {
@@ -1549,6 +1547,46 @@ dentry_is_dot_or_dotdot(const struct wim_dentry *dentry)
        return false;
 }
 
+static bool
+dentry_contains_embedded_null(const struct wim_dentry *dentry)
+{
+       for (unsigned i = 0; i < dentry->d_name_nbytes / 2; i++)
+               if (dentry->d_name[i] == cpu_to_le16('\0'))
+                       return true;
+       return false;
+}
+
+static bool
+should_ignore_dentry(struct wim_dentry *dir, const struct wim_dentry *dentry)
+{
+       /* All dentries except the root must be named. */
+       if (!dentry_has_long_name(dentry)) {
+               WARNING("Ignoring unnamed file in directory \"%"TS"\"",
+                       dentry_full_path(dir));
+               return true;
+       }
+
+       /* Don't allow files named "." or "..".  Such filenames could be used in
+        * path traversal attacks. */
+       if (dentry_is_dot_or_dotdot(dentry)) {
+               WARNING("Ignoring file named \".\" or \"..\" in directory "
+                       "\"%"TS"\"", dentry_full_path(dir));
+               return true;
+       }
+
+       /* Don't allow filenames containing embedded null characters.  Although
+        * the null character is already considered an unsupported character for
+        * extraction by all targets, it is probably a good idea to just forbid
+        * such names entirely. */
+       if (dentry_contains_embedded_null(dentry)) {
+               WARNING("Ignoring filename with embedded null character in "
+                       "directory \"%"TS"\"", dentry_full_path(dir));
+               return true;
+       }
+
+       return false;
+}
+
 static int
 read_dentry_tree_recursive(const u8 * restrict buf, size_t buf_len,
                           struct wim_dentry * restrict dir, unsigned depth)
@@ -1575,18 +1613,8 @@ read_dentry_tree_recursive(const u8 * restrict buf, size_t buf_len,
                if (child == NULL)
                        return 0;
 
-               /* All dentries except the root should be named.  */
-               if (unlikely(!dentry_has_long_name(child))) {
-                       WARNING("Ignoring unnamed dentry in "
-                               "directory \"%"TS"\"", dentry_full_path(dir));
-                       free_dentry(child);
-                       continue;
-               }
-
-               /* Don't allow files named "." or "..".  */
-               if (unlikely(dentry_is_dot_or_dotdot(child))) {
-                       WARNING("Ignoring file named \".\" or \"..\"; "
-                               "potentially malicious archive!!!");
+               /* Ignore dentries with bad names.  */
+               if (unlikely(should_ignore_dentry(dir, child))) {
                        free_dentry(child);
                        continue;
                }