Files
bpfire/src/patches/cpio-2.6-security_fixes-1.patch
ms ad9d4caf99 Ramdisk-Arbeit nahezu beendet.
git-svn-id: http://svn.ipfire.org/svn/ipfire/trunk@451 ea5c0bd1-69bd-2848-81d8-4f18e57aeed8
2007-03-19 20:25:01 +00:00

371 lines
13 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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, &times) < 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 ();