From 64a788323f731f85a631ec5c348926046635ebc2 Mon Sep 17 00:00:00 2001 From: Peter Vrabec Date: Tue, 17 May 2005 12:13:59 +0000 Subject: [PATCH] - fix #156314 (CAN-2005-1229) cpio directory traversal issue - fix some gcc warnings --- cpio-2.6-dirTraversal.patch | 193 ++++++++++++++++++++++++++++++++++++ cpio-2.6-warnings.patch | 172 ++++++++++++++++++++++++++++++++ cpio.spec | 10 +- 3 files changed, 374 insertions(+), 1 deletion(-) create mode 100644 cpio-2.6-dirTraversal.patch create mode 100644 cpio-2.6-warnings.patch diff --git a/cpio-2.6-dirTraversal.patch b/cpio-2.6-dirTraversal.patch new file mode 100644 index 0000000..69fe530 --- /dev/null +++ b/cpio-2.6-dirTraversal.patch @@ -0,0 +1,193 @@ +--- 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. */ diff --git a/cpio-2.6-warnings.patch b/cpio-2.6-warnings.patch new file mode 100644 index 0000000..f7e84f1 --- /dev/null +++ b/cpio-2.6-warnings.patch @@ -0,0 +1,172 @@ +2005-05-04 Dmitry V. Levin + + Deal with compilation warnings generated by gcc compiler. + + * src/copyin.c (list_file, copyin_regular_file, long_format, + process_copy_in): Fix format strings. + (create_defered_links_to_skipped): Remove unused variable + `link_res'. + (process_copy_in): Initialize tty_in, tty_out and rename_in. + * src/copyout.c (write_out_header): Initialize dev along with + rdev. + * src/tar.c (is_tar_filename_too_long): Remove unused variable `p'; + * src/util.c: Include and + (sparse_write): Add forward declaration. Initialize write_count + and cur_write_start variables. + (copy_files_disk_to_tape, copy_files_disk_to_disk): Add + parentheses around assignment. + +diff -uprk.orig cpio-2.6.orig/src/copyin.c cpio-2.6/src/copyin.c +--- cpio-2.6.orig/src/copyin.c 2004-09-08 11:10:02 +0000 ++++ cpio-2.6/src/copyin.c 2005-05-04 12:43:42 +0000 +@@ -176,7 +176,7 @@ list_file(struct new_cpio_header* file_h + #endif + if (crc != file_hdr->c_chksum) + { +- error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"), ++ error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"), + file_hdr->c_name, crc, file_hdr->c_chksum); + } + } +@@ -307,7 +307,6 @@ create_defered_links_to_skipped (struct + int ino; + int maj; + int min; +- int link_res; + if (file_hdr->c_filesize == 0) + { + /* The file doesn't have any data attached to it so we don't have +@@ -541,7 +540,7 @@ copyin_regular_file (struct new_cpio_hea + if (archive_format == arf_crcascii) + { + if (crc != file_hdr->c_chksum) +- error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"), ++ error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"), + file_hdr->c_name, crc, file_hdr->c_chksum); + } + tape_skip_padding (in_file_des, file_hdr->c_filesize); +@@ -563,7 +562,7 @@ copyin_regular_file (struct new_cpio_hea + if (archive_format == arf_crcascii) + { + if (crc != file_hdr->c_chksum) +- error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"), ++ error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"), + file_hdr->c_name, crc, file_hdr->c_chksum); + } + +@@ -897,7 +896,7 @@ long_format (struct new_cpio_header *fil + } + tbuf[16] = '\0'; + +- printf ("%s %3u ", mbuf, file_hdr->c_nlink); ++ printf ("%s %3lu ", mbuf, file_hdr->c_nlink); + + if (numeric_uid) + printf ("%-8u %-8u ", (unsigned int) file_hdr->c_uid, +@@ -908,7 +907,7 @@ long_format (struct new_cpio_header *fil + + if ((file_hdr->c_mode & CP_IFMT) == CP_IFCHR + || (file_hdr->c_mode & CP_IFMT) == CP_IFBLK) +- printf ("%3u, %3u ", file_hdr->c_rdev_maj, ++ printf ("%3lu, %3lu ", file_hdr->c_rdev_maj, + file_hdr->c_rdev_min); + else + printf ("%8lu ", file_hdr->c_filesize); +@@ -1342,9 +1341,9 @@ void + process_copy_in () + { + char done = false; /* True if trailer reached. */ +- FILE *tty_in; /* Interactive file for rename option. */ +- FILE *tty_out; /* Interactive file for rename option. */ +- FILE *rename_in; /* Batch file for rename option. */ ++ FILE *tty_in = NULL; /* Interactive file for rename option. */ ++ FILE *tty_out = NULL; /* Interactive file for rename option. */ ++ FILE *rename_in = NULL; /* Batch file for rename option. */ + struct stat file_stat; /* Output file stat record. */ + struct new_cpio_header file_hdr; /* Output header information. */ + int in_file_des; /* Input file descriptor. */ +@@ -1530,7 +1529,7 @@ process_copy_in () + tape_skip_padding (in_file_des, file_hdr.c_filesize); + if (crc != file_hdr.c_chksum) + { +- error (0, 0, _("%s: checksum error (0x%x, should be 0x%x)"), ++ error (0, 0, _("%s: checksum error (0x%lx, should be 0x%lx)"), + file_hdr.c_name, crc, file_hdr.c_chksum); + } + /* Debian hack: -v and -V now work with --only-verify-crc. +diff -uprk.orig cpio-2.6.orig/src/copyout.c cpio-2.6/src/copyout.c +--- cpio-2.6.orig/src/copyout.c 2004-10-14 09:14:03 +0000 ++++ cpio-2.6/src/copyout.c 2005-05-04 12:41:08 +0000 +@@ -346,7 +346,7 @@ write_out_header (struct new_cpio_header + #endif + file_hdr->c_filesize = makedev (file_hdr->c_rdev_maj, + file_hdr->c_rdev_min); +- rdev = 1; ++ dev = rdev = 1; + break; + default: + dev = makedev (file_hdr->c_dev_maj, file_hdr->c_dev_min); +diff -uprk.orig cpio-2.6.orig/src/tar.c cpio-2.6/src/tar.c +--- cpio-2.6.orig/src/tar.c 2004-10-14 09:33:41 +0000 ++++ cpio-2.6/src/tar.c 2005-05-04 12:41:47 +0000 +@@ -473,7 +473,6 @@ is_tar_filename_too_long (char *name) + { + int whole_name_len; + int prefix_name_len; +- char *p; + + whole_name_len = strlen (name); + if (whole_name_len <= TARNAMESIZE) +diff -uprk.orig cpio-2.6.orig/src/util.c cpio-2.6/src/util.c +--- cpio-2.6.orig/src/util.c 2004-09-08 10:44:49 +0000 ++++ cpio-2.6/src/util.c 2005-05-04 13:13:24 +0000 +@@ -24,6 +24,8 @@ + #include "dstring.h" + #include "extern.h" + #include ++#include ++#include + + #include + +@@ -38,6 +40,8 @@ + extern int errno; + #endif + ++int sparse_write (int fildes, char *buf, unsigned int nbyte); ++ + /* Write `output_size' bytes of `output_buffer' to file + descriptor OUT_DES and reset `output_size' and `out_buff'. */ + +@@ -471,9 +475,9 @@ copy_files_disk_to_tape (int in_des, int + while (num_bytes > 0) + { + if (input_size == 0) +- if (rc = disk_fill_input_buffer (in_des, ++ if ((rc = disk_fill_input_buffer (in_des, + num_bytes < DISK_IO_BLOCK_SIZE ? +- num_bytes : DISK_IO_BLOCK_SIZE)) ++ num_bytes : DISK_IO_BLOCK_SIZE))) + { + if (rc > 0) + error (0, 0, _("File %s shrunk by %ld bytes, padding with zeros"), +@@ -517,7 +521,7 @@ copy_files_disk_to_disk (int in_des, int + while (num_bytes > 0) + { + if (input_size == 0) +- if (rc = disk_fill_input_buffer (in_des, num_bytes)) ++ if ((rc = disk_fill_input_buffer (in_des, num_bytes))) + { + if (rc > 0) + error (0, 0, _("File %s shrunk by %ld bytes, padding with zeros"), +@@ -1157,8 +1161,8 @@ sparse_write (int fildes, char *buf, uns + int complete_block_count; + int leftover_bytes_count; + int seek_count; +- int write_count; +- char *cur_write_start; ++ int write_count = 0; ++ char *cur_write_start = buf; + int lseek_rc; + int write_rc; + int i; diff --git a/cpio.spec b/cpio.spec index 0c5f77e..08bb14d 100644 --- a/cpio.spec +++ b/cpio.spec @@ -6,7 +6,7 @@ Summary: A GNU archiving program. Name: cpio Version: 2.6 -Release: 6 +Release: 7 License: GPL Group: Applications/Archiving URL: http://www.gnu.org/software/cpio/ @@ -17,6 +17,8 @@ Patch14: cpio-2.6-lfs.patch Patch16: cpio-2.6-lstat.patch Patch17: cpio-2.6-umask.patch Patch18: cpio-2.6-chmodRaceC.patch +Patch19: cpio-2.6-dirTraversal.patch +Patch20: cpio-2.6-warnings.patch %ifnos linux Prereq: /sbin/rmt @@ -47,6 +49,8 @@ Install cpio if you need a program to manage file archives. %patch16 -p1 -b .lstat %patch17 -p1 -b .umask %patch18 -p1 -b .chmodRaceC +%patch19 -p1 -b .dirTraversal +%patch20 -p1 -b .warnings autoheader @@ -97,6 +101,10 @@ fi %{_infodir}/*.info* %changelog +* Tue May 17 2005 Peter Vrabec 2.6-7 +- fix #156314 (CAN-2005-1229) cpio directory traversal issue +- fix some gcc warnings + * Mon Apr 25 2005 Peter Vrabec 2.6-6 - fix race condition (#155749) - use find_lang macro