--- cpio-2.6/doc/cpio.1.dirTraversal 2005-05-17 13:18:23.554759017 +0200 +++ cpio-2.6/doc/cpio.1 2005-05-17 13:19:08.178249507 +0200 @@ -20,7 +20,7 @@ [\-\-unconditional] [\-\-verbose] [\-\-block-size=blocks] [\-\-swap-halfwords] [\-\-io-size=bytes] [\-\-pattern-file=file] [\-\-format=format] [\-\-owner=[user][:.][group]] [\-\-no-preserve-owner] [\-\-message=message] -[\-\-force\-local] [\-\-no\-absolute\-filenames] [\-\-sparse] +[\-\-force\-local] [\-\-absolute\-filenames] [\-\-sparse] [\-\-only\-verify\-crc] [\-\-quiet] [\-\-rsh-command=command] [\-\-help] [\-\-version] [pattern...] [< archive] --- cpio-2.6/doc/cpio.info.dirTraversal 2005-05-17 13:20:29.473392159 +0200 +++ cpio-2.6/doc/cpio.info 2005-05-17 13:30:53.812050889 +0200 @@ -203,7 +203,7 @@ [--swap-halfwords] [--io-size=bytes] [--pattern-file=file] [--format=format] [--owner=[user][:.][group]] [--no-preserve-owner] [--message=message] [--help] [--version] - [-no-absolute-filenames] [--sparse] [-only-verify-crc] [-quiet] + [--absolute-filenames] [--sparse] [-only-verify-crc] [-quiet] [--rsh-command=command] [pattern...] [< archive]  @@ -359,9 +359,9 @@ Show numeric UID and GID instead of translating them into names when using the `--verbose option'. -`--no-absolute-filenames' - Create all files relative to the current directory in copy-in - mode, even if they have an absolute file name in the archive. +`--absolute-filenames' + Do not strip leading file name components that contain ".." + and leading slashes from file names in copy-in mode `--no-preserve-owner' Do not change the ownership of the files; leave them owned by the --- cpio-2.6/src/main.c.dirTraversal 2005-05-17 12:10:15.952492515 +0200 +++ cpio-2.6/src/main.c 2005-05-17 12:10:15.965490607 +0200 @@ -41,6 +41,7 @@ enum cpio_options { NO_ABSOLUTE_FILENAMES_OPTION=256, + ABSOLUTE_FILENAMES_OPTION, NO_PRESERVE_OWNER_OPTION, ONLY_VERIFY_CRC_OPTION, RENAME_BATCH_FILE_OPTION, @@ -134,6 +135,8 @@ N_("In copy-in mode, read additional patterns specifying filenames to extract or list from FILE"), 210}, {"no-absolute-filenames", NO_ABSOLUTE_FILENAMES_OPTION, 0, 0, N_("Create all files relative to the current directory"), 210}, + {"absolute-filenames", ABSOLUTE_FILENAMES_OPTION, 0, 0, + N_("do not strip leading file name components that contain \"..\" and leading slashes from file names"), 210}, {"only-verify-crc", ONLY_VERIFY_CRC_OPTION, 0, 0, N_("When reading a CRC format archive in copy-in mode, only verify the CRC's of each file in the archive, don't actually extract the files"), 210}, {"rename", 'r', 0, 0, @@ -393,7 +396,11 @@ break; case NO_ABSOLUTE_FILENAMES_OPTION: /* --no-absolute-filenames */ - no_abs_paths_flag = true; + abs_paths_flag = false; + break; + + case ABSOLUTE_FILENAMES_OPTION: /* --absolute-filenames */ + abs_paths_flag = true; break; case NO_PRESERVE_OWNER_OPTION: /* --no-preserve-owner */ @@ -632,7 +639,7 @@ _("--append is used but no archive file name is given (use -F or -O options"))); CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--create"); - CHECK_USAGE(no_abs_paths_flag, "--no-absolute-pathnames", "--create"); + CHECK_USAGE(abs_paths_flag, "--absolute-pathnames", "--create"); CHECK_USAGE(input_archive_name, "-I", "--create"); if (archive_name && output_archive_name) USAGE_ERROR ((0, 0, _("Both -O and -F are used in copy-out mode"))); @@ -659,7 +666,7 @@ CHECK_USAGE(rename_flag, "--rename", "--pass-through"); CHECK_USAGE(append_flag, "--append", "--pass-through"); CHECK_USAGE(rename_batch_file, "--rename-batch-file", "--pass-through"); - CHECK_USAGE(no_abs_paths_flag, "--no-absolute-pathnames", + CHECK_USAGE(abs_paths_flag, "--absolute-pathnames", "--pass-through"); CHECK_USAGE(to_stdout_option, "--to-stdout", "--pass-through"); --- cpio-2.6/src/copyin.c.dirTraversal 2005-05-17 12:10:15.957491781 +0200 +++ cpio-2.6/src/copyin.c 2005-05-17 12:10:15.962491047 +0200 @@ -25,6 +25,7 @@ #include "dstring.h" #include "extern.h" #include "defer.h" +#include "dirname.h" #include #ifndef FNM_PATHNAME #include @@ -1349,6 +1350,53 @@ } } +/* Return a safer suffix of FILE_NAME, or "." if it has no safer + suffix. Check for fully specified file names and other atrocities. */ + +static const char * +safer_name_suffix (char const *file_name) +{ + char const *p; + + /* Skip file system prefixes, leading file name components that contain + "..", and leading slashes. */ + + size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (file_name); + + for (p = file_name + prefix_len; *p;) + { + if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2])) + prefix_len = p + 2 - file_name; + + do + { + char c = *p++; + if (ISSLASH (c)) + break; + } + while (*p); + } + + for (p = file_name + prefix_len; ISSLASH (*p); p++) + continue; + prefix_len = p - file_name; + + if (prefix_len) + { + char *prefix = alloca (prefix_len + 1); + memcpy (prefix, file_name, prefix_len); + prefix[prefix_len] = '\0'; + + + error (0, 0, _("Removing leading `%s' from member names"), prefix); + } + + if (!*p) + p = "."; + + return p; +} + /* Read the collection from standard input and create files in the file system. */ @@ -1459,18 +1507,11 @@ /* Do we have to ignore absolute paths, and if so, does the filename have an absolute path? */ - if (no_abs_paths_flag && file_hdr.c_name && file_hdr.c_name [0] == '/') + if (!abs_paths_flag && file_hdr.c_name && file_hdr.c_name [0]) { - char *p; + const char *p = safer_name_suffix (file_hdr.c_name); - p = file_hdr.c_name; - while (*p == '/') - ++p; - if (*p == '\0') - { - strcpy (file_hdr.c_name, "."); - } - else + if (p != file_hdr.c_name) { /* Debian hack: file_hrd.c_name is sometimes set to point to static memory by code in tar.c. This --- cpio-2.6/src/extern.h.dirTraversal 2005-05-17 12:10:15.944493689 +0200 +++ cpio-2.6/src/extern.h 2005-05-17 12:10:15.963490900 +0200 @@ -46,7 +46,7 @@ extern int sparse_flag; extern int quiet_flag; extern int only_verify_crc_flag; -extern int no_abs_paths_flag; +extern int abs_paths_flag; extern unsigned int warn_option; /* Values for warn_option */ --- cpio-2.6/src/global.c.dirTraversal 2004-09-08 12:23:44.000000000 +0200 +++ cpio-2.6/src/global.c 2005-05-17 12:10:15.964490753 +0200 @@ -100,7 +100,7 @@ int only_verify_crc_flag = false; /* If true, don't use any absolute paths, prefix them by `./'. */ -int no_abs_paths_flag = false; +int abs_paths_flag = false; #ifdef DEBUG_CPIO /* If true, print debugging information. */