diff --git a/cpio-2.6-chmodRaceC.patch b/cpio-2.6-chmodRaceC.patch index a27d258..c5c293e 100644 --- a/cpio-2.6-chmodRaceC.patch +++ b/cpio-2.6-chmodRaceC.patch @@ -1,18 +1,34 @@ ---- cpio-2.6/src/copyin.c.chmodRaceC 2005-04-25 13:19:34.079310381 +0200 -+++ cpio-2.6/src/copyin.c 2005-04-25 14:09:32.514889697 +0200 -@@ -389,19 +389,26 @@ +--- cpio-2.6/src/copyin.c.chmodRaceC 2005-07-01 14:23:04.000000000 +0200 ++++ cpio-2.6/src/copyin.c 2005-07-01 14:46:34.000000000 +0200 +@@ -184,11 +184,12 @@ + + static int + try_existing_file(struct new_cpio_header* 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) +@@ -198,6 +199,7 @@ + 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 +@@ -389,19 +391,20 @@ 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, @@ -24,25 +40,19 @@ /* 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); + error (0, errno, "%s", d->header.c_name); + + if (close (out_file_des) < 0) - error (0, errno, "%s", d->header.c_name); ++ error (0, errno, "%s", d->header.c_name); + if (retain_time_flag) { times.actime = times.modtime = d->header.c_mtime; -@@ -557,6 +564,25 @@ +@@ -557,6 +560,19 @@ 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, @@ -58,7 +68,7 @@ if (close (out_file_des) < 0) error (0, errno, "%s", file_hdr->c_name); -@@ -567,18 +593,6 @@ +@@ -567,18 +583,6 @@ file_hdr->c_name, crc, file_hdr->c_chksum); } @@ -77,7 +87,7 @@ if (retain_time_flag) { struct utimbuf times; /* For setting file times. */ -@@ -589,7 +603,7 @@ +@@ -589,7 +593,7 @@ if (utime (file_hdr->c_name, ×) < 0) error (0, errno, "%s", file_hdr->c_name); } @@ -86,8 +96,81 @@ tape_skip_padding (in_file_des, file_hdr->c_filesize); if (file_hdr->c_nlink > 1 && (archive_format == arf_newascii || archive_format == arf_crcascii) ) +@@ -603,7 +607,7 @@ + } + + static void +-copyin_directory(struct new_cpio_header* file_hdr, int existing_dir) ++copyin_directory(struct new_cpio_header* file_hdr, int existing_dir, mode_t existing_mode) + { + int res; /* Result of various function calls. */ + #ifdef HPUX_CDF +@@ -646,14 +650,23 @@ + 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; ++ else ++ { ++ 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) + { +@@ -742,12 +755,12 @@ + 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) +@@ -826,9 +839,10 @@ + copyin_file (struct new_cpio_header* file_hdr, int in_file_des) + { + int existing_dir; ++ 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. */ +@@ -839,7 +853,7 @@ + break; + + case CP_IFDIR: +- copyin_directory(file_hdr, existing_dir); ++ copyin_directory(file_hdr, existing_dir, existing_mode); + break; + + case CP_IFCHR: --- cpio-2.6/src/copypass.c.chmodRaceC 2004-09-06 14:09:04.000000000 +0200 -+++ cpio-2.6/src/copypass.c 2005-04-25 14:09:38.135076926 +0200 ++++ cpio-2.6/src/copypass.c 2005-07-01 14:50:46.000000000 +0200 @@ -181,19 +181,25 @@ } if (close (in_file_des) < 0) @@ -111,11 +194,54 @@ /* 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); + error (0, errno, "%s", output_name.ds_string); + + if (close (out_file_des) < 0) - error (0, errno, "%s", output_name.ds_string); ++ error (0, errno, "%s", output_name.ds_string); + if (reset_time_flag) { times.actime = in_file_stat.st_atime; +@@ -240,15 +246,24 @@ + 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) + { +@@ -311,12 +326,12 @@ + + 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) diff --git a/cpio-2.6-lfs.patch b/cpio-2.6-lfs.patch index e34b287..ff1f6ae 100644 --- a/cpio-2.6-lfs.patch +++ b/cpio-2.6-lfs.patch @@ -1,31 +1,43 @@ ---- cpio-2.6/src/extern.h.lfs 2004-09-08 10:49:57.000000000 +0000 -+++ cpio-2.6/src/extern.h 2005-01-14 14:10:09.006784175 +0000 +--- cpio-2.6/src/copyin.c.lfs 2005-07-01 13:48:05.000000000 +0200 ++++ cpio-2.6/src/copyin.c 2005-07-01 13:48:18.000000000 +0200 +@@ -106,7 +106,7 @@ + header type. */ + + static void +-tape_skip_padding (int in_file_des, int offset) ++tape_skip_padding (int in_file_des, unsigned long offset) + { + int pad; + +--- cpio-2.6/src/extern.h.lfs 2004-09-08 12:49:57.000000000 +0200 ++++ cpio-2.6/src/extern.h 2005-07-01 13:47:20.000000000 +0200 @@ -161,13 +161,13 @@ void tape_empty_output_buffer P_((int out_des)); void disk_empty_output_buffer P_((int out_des)); void swahw_array P_((char *ptr, int count)); -void tape_buffered_write P_((char *in_buf, int out_des, long num_bytes)); -+void tape_buffered_write P_((char *in_buf, int out_des, off_t num_bytes)); ++void tape_buffered_write P_((char *in_buf, int out_des, unsigned long num_bytes)); void tape_buffered_read P_((char *in_buf, int in_des, long num_bytes)); int tape_buffered_peek P_((char *peek_buf, int in_des, int num_bytes)); - void tape_toss_input P_((int in_des, long num_bytes)); +-void tape_toss_input P_((int in_des, long num_bytes)); -void copy_files_tape_to_disk P_((int in_des, int out_des, long num_bytes)); -void copy_files_disk_to_tape P_((int in_des, int out_des, long num_bytes, char *filename)); -void copy_files_disk_to_disk P_((int in_des, int out_des, long num_bytes, char *filename)); -+void copy_files_tape_to_disk P_((int in_des, int out_des, off_t num_bytes)); -+void copy_files_disk_to_tape P_((int in_des, int out_des, off_t num_bytes, char *filename)); -+void copy_files_disk_to_disk P_((int in_des, int out_des, off_t num_bytes, char *filename)); ++void tape_toss_input P_((int in_des, unsigned long num_bytes)); ++void copy_files_tape_to_disk P_((int in_des, int out_des, unsigned long num_bytes)); ++void copy_files_disk_to_tape P_((int in_des, int out_des, unsigned long num_bytes, char *filename)); ++void copy_files_disk_to_disk P_((int in_des, int out_des, unsigned long num_bytes, char *filename)); void warn_if_file_changed P_((char *file_name, unsigned long old_file_size, unsigned long old_file_mtime)); void create_all_directories P_((char *name)); ---- cpio-2.6/src/util.c.lfs 2004-09-08 10:44:49.000000000 +0000 -+++ cpio-2.6/src/util.c 2005-01-14 14:30:33.448133098 +0000 +--- cpio-2.6/src/util.c.lfs 2004-09-08 12:44:49.000000000 +0200 ++++ cpio-2.6/src/util.c 2005-07-01 13:56:49.000000000 +0200 @@ -207,7 +207,7 @@ Exit with an error if end of file is reached. */ static int -disk_fill_input_buffer (int in_des, int num_bytes) -+disk_fill_input_buffer (int in_des, off_t num_bytes) ++disk_fill_input_buffer (int in_des, unsigned long num_bytes) { in_buff = input_buffer; num_bytes = (num_bytes < DISK_IO_BLOCK_SIZE) ? num_bytes : DISK_IO_BLOCK_SIZE; @@ -34,10 +46,10 @@ void -tape_buffered_write (char *in_buf, int out_des, long num_bytes) -+tape_buffered_write (char *in_buf, int out_des, off_t num_bytes) ++tape_buffered_write (char *in_buf, int out_des, unsigned long num_bytes) { - register long bytes_left = num_bytes; /* Bytes needing to be copied. */ -+ register off_t bytes_left = num_bytes; /* Bytes needing to be copied. */ ++ register unsigned long bytes_left = num_bytes; /* Bytes needing to be copied. */ register long space_left; /* Room left in output buffer. */ while (bytes_left > 0) @@ -46,22 +58,38 @@ void -disk_buffered_write (char *in_buf, int out_des, long num_bytes) -+disk_buffered_write (char *in_buf, int out_des, off_t num_bytes) ++disk_buffered_write (char *in_buf, int out_des, unsigned long num_bytes) { - register long bytes_left = num_bytes; /* Bytes needing to be copied. */ -+ register off_t bytes_left = num_bytes; /* Bytes needing to be copied. */ ++ register unsigned long bytes_left = num_bytes; /* Bytes needing to be copied. */ register long space_left; /* Room left in output buffer. */ while (bytes_left > 0) -@@ -407,9 +407,9 @@ - write_nuls_to_file (long num_bytes, int out_des, +@@ -376,9 +376,9 @@ + /* Skip the next NUM_BYTES bytes of file descriptor IN_DES. */ + + void +-tape_toss_input (int in_des, long num_bytes) ++tape_toss_input (int in_des, unsigned long num_bytes) + { +- register long bytes_left = num_bytes; /* Bytes needing to be copied. */ ++ register unsigned long bytes_left = num_bytes; /* Bytes needing to be copied. */ + register long space_left; /* Bytes to copy from input buffer. */ + + while (bytes_left > 0) +@@ -404,12 +404,12 @@ + } + + static void +-write_nuls_to_file (long num_bytes, int out_des, ++write_nuls_to_file (unsigned long num_bytes, int out_des, void (*writer) (char *in_buf, int out_des, long num_bytes)) { - long blocks; -+ off_t blocks; ++ unsigned long blocks; long extra_bytes; - long i; -+ off_t i; ++ unsigned long i; blocks = num_bytes / 512; extra_bytes = num_bytes % 512; @@ -70,12 +98,12 @@ void -copy_files_tape_to_disk (int in_des, int out_des, long num_bytes) -+copy_files_tape_to_disk (int in_des, int out_des, off_t num_bytes) ++copy_files_tape_to_disk (int in_des, int out_des, unsigned long num_bytes) { - long size; - long k; -+ off_t size; -+ off_t k; ++ unsigned long size; ++ unsigned long k; while (num_bytes > 0) { @@ -84,16 +112,16 @@ void -copy_files_disk_to_tape (int in_des, int out_des, long num_bytes, -+copy_files_disk_to_tape (int in_des, int out_des, off_t num_bytes, ++copy_files_disk_to_tape (int in_des, int out_des, unsigned long num_bytes, char *filename) { - long size; - long k; -+ off_t size; -+ off_t k; ++ unsigned long size; ++ unsigned long k; int rc; - long original_num_bytes; -+ off_t original_num_bytes; ++ unsigned long original_num_bytes; original_num_bytes = num_bytes; @@ -115,15 +143,15 @@ void -copy_files_disk_to_disk (int in_des, int out_des, long num_bytes, -+copy_files_disk_to_disk (int in_des, int out_des, off_t num_bytes, ++copy_files_disk_to_disk (int in_des, int out_des, unsigned long num_bytes, char *filename) { - long size; - long k; - long original_num_bytes; -+ off_t size; -+ off_t k; -+ off_t original_num_bytes; ++ unsigned long size; ++ unsigned long k; ++ unsigned long original_num_bytes; int rc; original_num_bytes = num_bytes; diff --git a/cpio.spec b/cpio.spec index 08bb14d..ff2aeb0 100644 --- a/cpio.spec +++ b/cpio.spec @@ -6,7 +6,7 @@ Summary: A GNU archiving program. Name: cpio Version: 2.6 -Release: 7 +Release: 8 License: GPL Group: Applications/Archiving URL: http://www.gnu.org/software/cpio/ @@ -101,6 +101,10 @@ fi %{_infodir}/*.info* %changelog +* Fri Jul 01 2005 Peter Vrabec 2.6-8 +- fix large file support, archive >4GiB, archive members <4GiB (#160056) +- fix race condition holes, use mode 0700 for dir creation + * Tue May 17 2005 Peter Vrabec 2.6-7 - fix #156314 (CAN-2005-1229) cpio directory traversal issue - fix some gcc warnings