X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fpatches%2Fcpio-2.6-security_fixes-1.patch;fp=src%2Fpatches%2Fcpio-2.6-security_fixes-1.patch;h=083c7858d4e3e0fee38f719742c887e116ff004b;hb=ad9d4caf99c5f34895882da0343b8c441a237a02;hp=0000000000000000000000000000000000000000;hpb=330345c2824b2e0d7e63cfe952af3e4a6cc2cd3b;p=people%2Fpmueller%2Fipfire-2.x.git diff --git a/src/patches/cpio-2.6-security_fixes-1.patch b/src/patches/cpio-2.6-security_fixes-1.patch new file mode 100644 index 0000000000..083c7858d4 --- /dev/null +++ b/src/patches/cpio-2.6-security_fixes-1.patch @@ -0,0 +1,370 @@ +Submitted By: Ken Moffat +Date: 2005-07-29 +Initial Package Version: 2.6 +Upstream Status: Unknown +Origin: from Mandrake +Description: Vulnerability fixes, rediffed so that they all apply with + -p1 and consolidated to single patch. Also applicable to earlier versions. +(1.) CAN-1999-1572 (still seems to apply to 2.6) cpio uses a 0 umask when +creating files with -O or -F options, which creates the files with mode 0666 +and allows local users to overwrite them. Fix originally fom debian. +(2.) CAN-2005-1111 Race condition in 2.6 and earlier allows local users to +modify permissions of arbitrary files via a hard-link attack. Fix +originally from fedora. +(3.) CAN-2005-1229 Directory traversal vulnerability allows remote +attackers to write to arbitrary directories via a dot dot in a cpio file. +Fix by Peter Vrabec at RedHat. + +diff -Naur cpio-2.6.vanilla/doc/cpio.1 cpio-2.6/doc/cpio.1 +--- cpio-2.6.vanilla/doc/cpio.1 2004-08-30 17:21:48.000000000 +0100 ++++ cpio-2.6/doc/cpio.1 2005-07-29 13:46:42.000000000 +0100 +@@ -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] + +diff -Naur cpio-2.6.vanilla/doc/cpio.info cpio-2.6/doc/cpio.info +--- cpio-2.6.vanilla/doc/cpio.info 2004-02-27 12:42:01.000000000 +0000 ++++ cpio-2.6/doc/cpio.info 2005-07-29 13:46:42.000000000 +0100 +@@ -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] + +  +@@ -358,9 +358,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 +diff -Naur cpio-2.6.vanilla/src/copyin.c cpio-2.6/src/copyin.c +--- cpio-2.6.vanilla/src/copyin.c 2004-09-08 12:10:02.000000000 +0100 ++++ cpio-2.6/src/copyin.c 2005-07-29 13:46:42.000000000 +0100 +@@ -25,6 +25,7 @@ + #include "dstring.h" + #include "extern.h" + #include "defer.h" ++#include "dirname.h" + #include + #ifndef FNM_PATHNAME + #include +@@ -389,19 +390,26 @@ + continue; + } + +- if (close (out_file_des) < 0) +- error (0, errno, "%s", d->header.c_name); +- ++ /* ++ * Avoid race condition. ++ * Set chown and chmod before closing the file desc. ++ * pvrabec@redhat.com ++ */ ++ + /* File is now copied; set attributes. */ + if (!no_chown_flag) +- if ((chown (d->header.c_name, ++ if ((fchown (out_file_des, + set_owner_flag ? set_owner : d->header.c_uid, + set_group_flag ? set_group : d->header.c_gid) < 0) + && errno != EPERM) + error (0, errno, "%s", d->header.c_name); + /* chown may have turned off some permissions we wanted. */ +- if (chmod (d->header.c_name, (int) d->header.c_mode) < 0) ++ if (fchmod (out_file_des, (int) d->header.c_mode) < 0) + error (0, errno, "%s", d->header.c_name); ++ ++ if (close (out_file_des) < 0) ++ error (0, errno, "%s", d->header.c_name); ++ + if (retain_time_flag) + { + times.actime = times.modtime = d->header.c_mtime; +@@ -557,6 +565,25 @@ + write (out_file_des, "", 1); + delayed_seek_count = 0; + } ++ ++ /* ++ * Avoid race condition. ++ * Set chown and chmod before closing the file desc. ++ * pvrabec@redhat.com ++ */ ++ ++ /* File is now copied; set attributes. */ ++ if (!no_chown_flag) ++ if ((fchown (out_file_des, ++ set_owner_flag ? set_owner : file_hdr->c_uid, ++ set_group_flag ? set_group : file_hdr->c_gid) < 0) ++ && errno != EPERM) ++ error (0, errno, "%s", file_hdr->c_name); ++ ++ /* chown may have turned off some permissions we wanted. */ ++ if (fchmod (out_file_des, (int) file_hdr->c_mode) < 0) ++ error (0, errno, "%s", file_hdr->c_name); ++ + if (close (out_file_des) < 0) + error (0, errno, "%s", file_hdr->c_name); + +@@ -567,18 +594,6 @@ + file_hdr->c_name, crc, file_hdr->c_chksum); + } + +- /* File is now copied; set attributes. */ +- if (!no_chown_flag) +- if ((chown (file_hdr->c_name, +- set_owner_flag ? set_owner : file_hdr->c_uid, +- set_group_flag ? set_group : file_hdr->c_gid) < 0) +- && errno != EPERM) +- error (0, errno, "%s", file_hdr->c_name); +- +- /* chown may have turned off some permissions we wanted. */ +- if (chmod (file_hdr->c_name, (int) file_hdr->c_mode) < 0) +- error (0, errno, "%s", file_hdr->c_name); +- + if (retain_time_flag) + { + struct utimbuf times; /* For setting file times. */ +@@ -589,7 +604,7 @@ + if (utime (file_hdr->c_name, ×) < 0) + error (0, errno, "%s", file_hdr->c_name); + } +- ++ + tape_skip_padding (in_file_des, file_hdr->c_filesize); + if (file_hdr->c_nlink > 1 + && (archive_format == arf_newascii || archive_format == arf_crcascii) ) +@@ -1335,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. */ + +@@ -1445,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 +diff -Naur cpio-2.6.vanilla/src/copypass.c cpio-2.6/src/copypass.c +--- cpio-2.6.vanilla/src/copypass.c 2004-09-06 13:09:04.000000000 +0100 ++++ cpio-2.6/src/copypass.c 2005-07-29 13:46:07.000000000 +0100 +@@ -181,19 +181,25 @@ + } + if (close (in_file_des) < 0) + error (0, errno, "%s", input_name.ds_string); +- if (close (out_file_des) < 0) +- error (0, errno, "%s", output_name.ds_string); +- ++ /* ++ * Avoid race condition. ++ * Set chown and chmod before closing the file desc. ++ * pvrabec@redhat.com ++ */ + /* Set the attributes of the new file. */ + if (!no_chown_flag) +- if ((chown (output_name.ds_string, ++ if ((fchown (out_file_des, + set_owner_flag ? set_owner : in_file_stat.st_uid, + set_group_flag ? set_group : in_file_stat.st_gid) < 0) + && errno != EPERM) + error (0, errno, "%s", output_name.ds_string); + /* chown may have turned off some permissions we wanted. */ +- if (chmod (output_name.ds_string, in_file_stat.st_mode) < 0) ++ if (fchmod (out_file_des, in_file_stat.st_mode) < 0) ++ error (0, errno, "%s", output_name.ds_string); ++ ++ if (close (out_file_des) < 0) + error (0, errno, "%s", output_name.ds_string); ++ + if (reset_time_flag) + { + times.actime = in_file_stat.st_atime; +diff -Naur cpio-2.6.vanilla/src/extern.h cpio-2.6/src/extern.h +--- cpio-2.6.vanilla/src/extern.h 2004-09-08 11:49:57.000000000 +0100 ++++ cpio-2.6/src/extern.h 2005-07-29 13:47:34.000000000 +0100 +@@ -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 */ +@@ -91,6 +91,7 @@ + extern char input_is_seekable; + extern char output_is_seekable; + extern char *program_name; ++extern mode_t sys_umask; + extern int (*xstat) (); + extern void (*copy_function) (); + +diff -Naur cpio-2.6.vanilla/src/global.c cpio-2.6/src/global.c +--- cpio-2.6.vanilla/src/global.c 2004-09-08 11:23:44.000000000 +0100 ++++ cpio-2.6/src/global.c 2005-07-29 13:47:34.000000000 +0100 +@@ -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. */ +@@ -195,6 +195,9 @@ + /* The name this program was run with. */ + char *program_name; + ++/* Debian hack to make the -d option honor the umask. */ ++mode_t sys_umask; ++ + /* A pointer to either lstat or stat, depending on whether + dereferencing of symlinks is done for input files. */ + int (*xstat) (); +diff -Naur cpio-2.6.vanilla/src/main.c cpio-2.6/src/main.c +--- cpio-2.6.vanilla/src/main.c 2004-11-23 00:42:18.000000000 +0000 ++++ cpio-2.6/src/main.c 2005-07-29 13:47:34.000000000 +0100 +@@ -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, +@@ -392,7 +395,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 */ +@@ -631,7 +638,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"))); +@@ -658,7 +665,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"); + +@@ -740,7 +747,6 @@ + textdomain (PACKAGE); + + program_name = argv[0]; +- umask (0); + + #ifdef __TURBOC__ + _fmode = O_BINARY; /* Put stdin and stdout in binary mode. */ +@@ -751,6 +757,7 @@ + #endif + + process_args (argc, argv); ++ sys_umask = umask (0); + + initialize_buffers (); +