tar et al: die if bb_copyfd_size copies less than asked for.
[oweals/busybox.git] / archival / libunarchive / get_header_tar.c
index 583f6f81175852b911a32f02e98ffb671921d0ac..beb8687c72ac3f0bc42ba7a51f36eeff064e6180 100644 (file)
@@ -157,7 +157,6 @@ char get_header_tar(archive_handle_t *archive_handle)
                        file_header->name = concat_path_file(tar.prefix, tar.name);
                } else
                        file_header->name = xstrdup(tar.name);
-               /* FIXME: add check for /../ attacks */
        }
 
        /* Set bits 12-15 of the files mode */
@@ -244,9 +243,15 @@ char get_header_tar(archive_handle_t *archive_handle)
                linkname = NULL;
        }
 #endif
+       if (!strncmp(file_header->name, "/../"+1, 3)
+        || strstr(file_header->name, "/../")
+       ) {
+               bb_error_msg_and_die("name with '..' encountered: '%s'",
+                               file_header->name);
+       }
 
        /* Strip trailing '/' in directories */
-       /* Must be done after mode is set as '/' is used to check if its a directory */
+       /* Must be done after mode is set as '/' is used to check if it's a directory */
        cp = last_char_is(file_header->name, '/');
 
        if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) {