mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-22 17:02:58 +02:00
git-svn-id: http://svn.ipfire.org/svn/ipfire/trunk@451 ea5c0bd1-69bd-2848-81d8-4f18e57aeed8
371 lines
13 KiB
Diff
371 lines
13 KiB
Diff
Submitted By: Ken Moffat <ken@kenmoffat.uklinux.net>
|
||
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 <rmt.h>
|
||
#ifndef FNM_PATHNAME
|
||
#include <fnmatch.h>
|
||
@@ -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 ();
|
||
|