]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/cpio-2.6-security_fixes-1.patch
Ramdisk-Arbeit nahezu beendet.
[people/pmueller/ipfire-2.x.git] / src / patches / cpio-2.6-security_fixes-1.patch
diff --git a/src/patches/cpio-2.6-security_fixes-1.patch b/src/patches/cpio-2.6-security_fixes-1.patch
new file mode 100644 (file)
index 0000000..083c785
--- /dev/null
@@ -0,0 +1,370 @@
+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]
\1f
+@@ -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) ();
\f
+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 ();