fix large file support, archive >4GiB, archive members <4GiB (#160056) fix
race condition holes, use mode 0700 for dir creation
This commit is contained in:
parent
64a788323f
commit
501abeb43f
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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 <pvrabec@redhat.com> 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 <pvrabec@redhat.com> 2.6-7
|
||||
- fix #156314 (CAN-2005-1229) cpio directory traversal issue
|
||||
- fix some gcc warnings
|
||||
|
Loading…
Reference in New Issue
Block a user