diff --git a/cpio-2.9-chmodRaceC.patch b/cpio-2.9-chmodRaceC.patch new file mode 100644 index 0000000..a1dad8a --- /dev/null +++ b/cpio-2.9-chmodRaceC.patch @@ -0,0 +1,139 @@ +--- src/copypass.c ++++ src/copypass.c +@@ -239,15 +239,23 @@ process_copy_pass () + cdf_flag = 1; + } + #endif +- res = mkdir (output_name.ds_string, in_file_stat.st_mode); ++ res = mkdir (output_name.ds_string, in_file_stat.st_mode & ~077); + + } + else +- res = 0; ++ { ++ if (!no_chown_flag && (out_file_stat.st_mode & 077) != 0 ++ && chmod (output_name.ds_string, out_file_stat.st_mode & 07700) < 0) ++ { ++ error (0, errno, "%s: chmod", output_name.ds_string); ++ continue; ++ } ++ res = 0; ++ } + if (res < 0 && create_dir_flag) + { + create_all_directories (output_name.ds_string); +- res = mkdir (output_name.ds_string, in_file_stat.st_mode); ++ res = mkdir (output_name.ds_string, in_file_stat.st_mode & ~077); + } + if (res < 0) + { +@@ -290,12 +298,12 @@ process_copy_pass () + + if (link_res < 0) + { +- res = mknod (output_name.ds_string, in_file_stat.st_mode, ++ res = mknod (output_name.ds_string, in_file_stat.st_mode & ~077, + in_file_stat.st_rdev); + if (res < 0 && create_dir_flag) + { + create_all_directories (output_name.ds_string); +- res = mknod (output_name.ds_string, in_file_stat.st_mode, ++ res = mknod (output_name.ds_string, in_file_stat.st_mode & ~077, + in_file_stat.st_rdev); + } + if (res < 0) +--- src/copyin.c ++++ src/copyin.c +@@ -186,11 +186,12 @@ list_file(struct cpio_file_stat* file_hd + + static int + try_existing_file (struct cpio_file_stat* file_hdr, int in_file_des, +- int *existing_dir) ++ int *existing_dir, mode_t *existing_mode) + { + struct stat file_stat; + + *existing_dir = false; ++ *existing_mode = 0; + if (lstat (file_hdr->c_name, &file_stat) == 0) + { + if (S_ISDIR (file_stat.st_mode) +@@ -200,6 +201,7 @@ try_existing_file (struct cpio_file_stat + we are trying to create, don't complain about + it. */ + *existing_dir = true; ++ *existing_mode = file_stat.st_mode; + return 0; + } + else if (!unconditional_flag +@@ -567,7 +569,7 @@ copyin_regular_file (struct cpio_file_st + } + + static void +-copyin_directory (struct cpio_file_stat *file_hdr, int existing_dir) ++copyin_directory (struct cpio_file_stat *file_hdr, int existing_dir, mode_t existing_mode) + { + int res; /* Result of various function calls. */ + #ifdef HPUX_CDF +@@ -610,14 +612,22 @@ copyin_directory (struct cpio_file_stat + cdf_flag = 1; + } + #endif +- res = mkdir (file_hdr->c_name, file_hdr->c_mode); ++ res = mkdir (file_hdr->c_name, file_hdr->c_mode & ~077); + } + else +- res = 0; ++ { ++ if (!no_chown_flag && (existing_mode & 077) != 0 ++ && chmod (file_hdr->c_name, existing_mode & 07700) < 0) ++ { ++ error (0, errno, "%s: chmod", file_hdr->c_name); ++ return; ++ } ++ res = 0; ++ } + if (res < 0 && create_dir_flag) + { + create_all_directories (file_hdr->c_name); +- res = mkdir (file_hdr->c_name, file_hdr->c_mode); ++ res = mkdir (file_hdr->c_name, file_hdr->c_mode & ~077); + } + if (res < 0) + { +@@ -692,12 +702,12 @@ copyin_device (struct cpio_file_stat* fi + return; + } + +- res = mknod (file_hdr->c_name, file_hdr->c_mode, ++ res = mknod (file_hdr->c_name, file_hdr->c_mode & ~077, + makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min)); + if (res < 0 && create_dir_flag) + { + create_all_directories (file_hdr->c_name); +- res = mknod (file_hdr->c_name, file_hdr->c_mode, ++ res = mknod (file_hdr->c_name, file_hdr->c_mode & ~077, + makedev (file_hdr->c_rdev_maj, file_hdr->c_rdev_min)); + } + if (res < 0) +@@ -772,9 +782,10 @@ static void + copyin_file (struct cpio_file_stat* file_hdr, int in_file_des) + { + int existing_dir=0; ++ mode_t existing_mode; + + if (!to_stdout_option +- && try_existing_file (file_hdr, in_file_des, &existing_dir) < 0) ++ && try_existing_file (file_hdr, in_file_des, &existing_dir, &existing_mode) < 0) + return; + + /* Do the real copy or link. */ +@@ -785,7 +796,7 @@ copyin_file (struct cpio_file_stat* file + break; + + case CP_IFDIR: +- copyin_directory (file_hdr, existing_dir); ++ copyin_directory(file_hdr, existing_dir, existing_mode); + break; + + case CP_IFCHR: diff --git a/cpio-2.9-paxlib-owl-alloca.patch b/cpio-2.9-paxlib-owl-alloca.patch new file mode 100644 index 0000000..a6382de --- /dev/null +++ b/cpio-2.9-paxlib-owl-alloca.patch @@ -0,0 +1,100 @@ +Patch from Sergey Poznyakoff for cpio +based on patch: +2007-08-15 Dmitry V. Levin + + Do not use alloca to avoid stack overflow with untrusted input. + + * lib/paxnames.c (hash_string_insert_direct): New function. + (hash_string_insert): Use it. + (hash_string_insert_data): New function. + (safer_name_suffix): Use it instead of hash_string_insert() + and alloca(). + +--- lib/paxnames.c ++++ lib/paxnames.c +@@ -36,15 +36,27 @@ + return strcmp (name1, name2) == 0; + } + +-/* Return zero if TABLE contains a copy of STRING; otherwise, insert a +- copy of STRING to TABLE and return 1. */ +-bool +-hash_string_insert (Hash_table **table, char const *string) ++/* Return zero if TABLE contains a LEN-character long prefix of STRING, ++ otherwise, insert a newly allocated copy of this prefix to TABLE and ++ return 1. If RETURN_PREFIX is not NULL, point it to the allocated ++ copy. */ ++static bool ++hash_string_insert_prefix (Hash_table **table, char const *string, size_t len, ++ const char **return_prefix) + { + Hash_table *t = *table; +- char *s = xstrdup (string); ++ char *s; + char *e; + ++ if (len) ++ { ++ s = xmalloc (len + 1); ++ memcpy (s, string, len); ++ s[len] = 0; ++ } ++ else ++ s = xstrdup (string); ++ + if (! ((t + || (*table = t = hash_initialize (0, 0, hash_string_hasher, + hash_string_compare, 0))) +@@ -52,7 +64,11 @@ + xalloc_die (); + + if (e == s) +- return 1; ++ { ++ if (return_prefix) ++ *return_prefix = s; ++ return 1; ++ } + else + { + free (s); +@@ -60,6 +76,14 @@ + } + } + ++/* Return zero if TABLE contains a copy of STRING; otherwise, insert a ++ copy of STRING to TABLE and return 1. */ ++bool ++hash_string_insert (Hash_table **table, char const *string) ++{ ++ return hash_string_insert_prefix (table, string, 0, NULL); ++} ++ + /* Return 1 if TABLE contains STRING. */ + bool + hash_string_lookup (Hash_table const *table, char const *string) +@@ -88,7 +112,8 @@ + If ABSOLUTE_NAMES is 0, strip filesystem prefix from the file name. */ + + char * +-safer_name_suffix (char const *file_name, bool link_target, bool absolute_names) ++safer_name_suffix (char const *file_name, bool link_target, ++ bool absolute_names) + { + char const *p; + +@@ -121,11 +146,9 @@ + + if (prefix_len) + { +- char *prefix = alloca (prefix_len + 1); +- memcpy (prefix, file_name, prefix_len); +- prefix[prefix_len] = '\0'; +- +- if (hash_string_insert (&prefix_table[link_target], prefix)) ++ const char **prefix; ++ if (hash_string_insert_prefix (&prefix_table[link_target], file_name, ++ prefix_len, &prefix)) + { + static char const *const diagnostic[] = + { diff --git a/cpio.changes b/cpio.changes index 4d56829..1dfe23a 100644 --- a/cpio.changes +++ b/cpio.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Fri Aug 17 10:31:21 CEST 2007 - lmichnovic@suse.cz + +- upstream fix: use of alloca can cause stack overflow + (paxlib-owl-alloca.patch) + +------------------------------------------------------------------- +Tue Aug 14 10:39:41 CEST 2007 - lmichnovic@suse.cz + +- CAN-2005-1111 is not fixed completely in 2.9 (chmodRaceC.patch) + based on fedora patch + ------------------------------------------------------------------- Wed Jul 25 13:14:53 CEST 2007 - lmichnovic@suse.cz diff --git a/cpio.spec b/cpio.spec index 7ab1d31..ae6e1e3 100644 --- a/cpio.spec +++ b/cpio.spec @@ -12,11 +12,11 @@ Name: cpio URL: http://www.gnu.org/software/cpio/cpio.html -License: GPL v2 or later +License: GPL v3 only Group: Productivity/Archiving/Compression Autoreqprov: on Version: 2.9 -Release: 2 +Release: 8 Summary: A Backup and Archiving Utility Source: cpio-2.9.tar.bz2 Patch1: cpio-2.9-no_rmt.patch @@ -25,22 +25,22 @@ Patch3: cpio-2.9-mt.patch Patch4: cpio-2.9-use_sbin_rmt.patch Patch5: cpio-2.9-open_nonblock.patch Patch6: cpio-2.9-lfs_correction.patch +Patch7: cpio-2.9-chmodRaceC.patch +Patch8: cpio-2.9-paxlib-owl-alloca.patch PreReq: %install_info_prereq BuildRoot: %{_tmppath}/%{name}-%{version}-build %description -This is GNU cpio, a program to manage archives of files. This package -also includes 'mt', a tape drive control program. Cpio copies files -into or out of a cpio or tar archive. An archive is a file that -contains other files plus information about them, such as their -pathname, owner, time stamps, and access permissions. The archive can -be another file on the disk, a magnetic tape, or a pipe. - -This package normally includes the program 'rmt', which provides remote -tape drive control. Because there is a compatible 'rmt' in the 'dump' -package, 'rmt' is not included in this package. If you are planning to -use the remote tape features provided by cpio, install the 'dump' -package as well. +GNU cpio is a program to manage archives of files. This package also +includes 'mt', a tape drive control program. Cpio copies files into or +out of a cpio or tar archive. An archive is a file that contains other +files plus information about them, such as their pathname, owner, time +stamps, and access permissions. The archive can be another file on the +disk, a magnetic tape, or a pipe. This package normally includes the +program 'rmt', which providesremote tape drive control. Because there +is a compatible 'rmt' in the'dump' package, 'rmt' is not included in +this package. If you are planningto use the remote tape features +provided by cpio, install the'dump' package as well. @@ -57,6 +57,8 @@ Authors: %patch4 %patch5 %patch6 +%patch7 +%patch8 chmod 755 . chmod u+w * chmod a+r * @@ -97,6 +99,12 @@ ln -sf ../../bin/cpio $RPM_BUILD_ROOT/usr/bin/cpio #/usr/share/locale/*/LC_MESSAGES/cpio.mo %changelog +* Fri Aug 17 2007 - lmichnovic@suse.cz +- upstream fix: use of alloca can cause stack overflow + (paxlib-owl-alloca.patch) +* Tue Aug 14 2007 - lmichnovic@suse.cz +- CAN-2005-1111 is not fixed completely in 2.9 (chmodRaceC.patch) + based on fedora patch * Wed Jul 25 2007 - lmichnovic@suse.cz - fixed types of variables for LFS support (*lfs_correction.patch) * Tue Jul 24 2007 - lmichnovic@suse.cz