Репозитории ALT
S: | 2.14.0.4.e3cc-alt1 |
5.1: | 2.10-alt3 |
4.1: | 2.10-alt2.M41.2 |
4.0: | 2.6-alt17.M40.1 |
3.0: | 2.6-alt14 |
Другие репозитории
Upstream: | 2.9 |
Группа :: Архивирование/Резервное копирование
Пакет: cpio
Главная Изменения Спек Патчи Sources Загрузить Gear Bugs and FR Repocop
Патч: cpio-2.6-alt-open-mkdir-mknod.patch
Скачать
Скачать
2005-05-11 Dmitry V. Levin <ldv@altlinux.org>
Fix race conditions in code which creates regular files, creates
directories and devices or sets its permissions, in copy-in and
copy-pass modes.
* src/copyin.c (try_existing_file): Add argument: existing_mode.
When `*existing_dir' is set to true, store file mode to
`*existing_mode'.
(create_final_defers, copyin_regular_file): Change open(2)
calls to use O_EXCL.
(copyin_directory): Change mkdir(2) and mknod(2) calls to use
safe permissions.
Add argument: existing_mode.
When reusing already existing directory, no_chown_flag is not
set and directory mode is too permissive, chmod it to safe mode
before chown(2) call.
(copyin_file): Pass existing_mode from try_existing_file()
to copyin_directory().
* src/copypass.c (process_copy_pass): Change open(2) calls to
use O_EXCL.
Change mkdir(2) and mknod(2) calls to use safe permissions.
When reusing already existing directory, no_chown_flag is not
set and directory mode is too permissive, chmod it to safe mode
before chown(2) call.
diff -uprk.orig cpio-2.6.orig/src/copyin.c cpio-2.6/src/copyin.c
--- cpio-2.6.orig/src/copyin.c 2005-05-11 12:20:17 +0000
+++ cpio-2.6/src/copyin.c 2005-05-11 13:39:03 +0000
@@ -185,11 +185,12 @@ list_file(struct new_cpio_header* file_h
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)
@@ -199,6 +200,7 @@ try_existing_file(struct new_cpio_header
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
@@ -375,12 +377,12 @@ create_final_defers ()
continue;
}
out_file_des = open (d->header.c_name,
- O_CREAT | O_WRONLY | O_BINARY, 0600);
+ O_CREAT | O_EXCL | O_WRONLY | O_BINARY, 0600);
if (out_file_des < 0 && create_dir_flag)
{
create_all_directories (d->header.c_name);
out_file_des = open (d->header.c_name,
- O_CREAT | O_WRONLY | O_BINARY,
+ O_CREAT | O_EXCL | O_WRONLY | O_BINARY,
0600);
}
if (out_file_des < 0)
@@ -497,13 +499,13 @@ copyin_regular_file (struct new_cpio_hea
/* If not linked, copy the contents of the file. */
out_file_des = open (file_hdr->c_name,
- O_CREAT | O_WRONLY | O_BINARY, 0600);
+ O_CREAT | O_EXCL | O_WRONLY | O_BINARY, 0600);
if (out_file_des < 0 && create_dir_flag)
{
create_all_directories (file_hdr->c_name);
out_file_des = open (file_hdr->c_name,
- O_CREAT | O_WRONLY | O_BINARY,
+ O_CREAT | O_EXCL | O_WRONLY | O_BINARY,
0600);
}
@@ -604,7 +606,8 @@ copyin_regular_file (struct new_cpio_hea
}
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
@@ -647,14 +650,22 @@ copyin_directory(struct new_cpio_header*
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)
{
@@ -743,12 +754,12 @@ copyin_device(struct new_cpio_header* 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)
@@ -827,9 +838,11 @@ static void
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. */
@@ -840,7 +853,7 @@ copyin_file (struct new_cpio_header* fil
break;
case CP_IFDIR:
- copyin_directory(file_hdr, existing_dir);
+ copyin_directory(file_hdr, existing_dir, existing_mode);
break;
case CP_IFCHR:
diff -uprk.orig cpio-2.6.orig/src/copypass.c cpio-2.6/src/copypass.c
--- cpio-2.6.orig/src/copypass.c 2005-05-11 12:20:17 +0000
+++ cpio-2.6/src/copypass.c 2005-05-11 13:44:28 +0000
@@ -157,12 +157,12 @@ process_copy_pass ()
continue;
}
out_file_des = open (output_name.ds_string,
- O_CREAT | O_WRONLY | O_BINARY, 0600);
+ O_CREAT | O_EXCL | O_WRONLY | O_BINARY, 0600);
if (out_file_des < 0 && create_dir_flag)
{
create_all_directories (output_name.ds_string);
out_file_des = open (output_name.ds_string,
- O_CREAT | O_WRONLY | O_BINARY, 0600);
+ O_CREAT | O_EXCL | O_WRONLY | O_BINARY, 0600);
}
if (out_file_des < 0)
{
@@ -243,15 +243,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)
{
@@ -314,12 +322,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)