From 55cee4b12b7e8b9d3b48038bbfb6a745a5a8632b Mon Sep 17 00:00:00 2001 From: Ondrej Vasik Date: Mar 10 2010 13:24:28 +0000 Subject: CVE-2010-0624 tar, cpio: Heap-based buffer overflow by expanding a specially-crafted archive (#572149), various fixes and enhancements from F-12 --- diff --git a/tar-1.19-xattrs-conf.patch b/tar-1.19-xattrs-conf.patch deleted file mode 100644 index 43632c3..0000000 --- a/tar-1.19-xattrs-conf.patch +++ /dev/null @@ -1,125 +0,0 @@ -diff -urNp tar-1.22-orig/config.hin tar-1.22/config.hin ---- tar-1.22-orig/config.hin 2009-03-05 08:08:07.000000000 +0100 -+++ tar-1.22/config.hin 2009-03-05 09:57:06.000000000 +0100 -@@ -131,6 +131,9 @@ - */ - #undef HAVE_ALLOCA_H - -+/* Define to 1 if you have the header file. */ -+#undef HAVE_ATTR_XATTR_H -+ - /* Define to 1 if you have the `btowc' function. */ - #undef HAVE_BTOWC - -@@ -372,12 +375,21 @@ - /* Define to 1 if you have the header file. */ - #undef HAVE_FEATURES_H - -+/* Define to 1 if you have the `fgetxattr' function. */ -+#undef HAVE_FGETXATTR -+ -+/* Define to 1 if you have the `flistxattr' function. */ -+#undef HAVE_FLISTXATTR -+ - /* Define to 1 if you have the header file. */ - #undef HAVE_FLOAT_H - - /* Define to 1 if you have the `flockfile' function. */ - #undef HAVE_FLOCKFILE - -+/* Define to 1 if you have the `fsetxattr' function. */ -+#undef HAVE_FSETXATTR -+ - /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ - #undef HAVE_FSEEKO - -@@ -423,6 +435,9 @@ - /* Define to 1 if you have the `gettimeofday' function. */ - #undef HAVE_GETTIMEOFDAY - -+/* Define to 1 if you have the `getxattr' function. */ -+#undef HAVE_GETXATTR -+ - /* Define to 1 if you have the header file. */ - #undef HAVE_GRP_H - -@@ -468,15 +483,30 @@ - /* Define to 1 if you have the `lchown' function. */ - #undef HAVE_LCHOWN - -+/* Define to 1 if you have the `lgetxattr' function. */ -+#undef HAVE_LGETXATTR -+ -+/* Define to 1 if you have the `acl' library (-lacl). */ -+#undef HAVE_LIBACL -+ - /* Define to 1 if you have the header file. */ - #undef HAVE_LIBINTL_H - -+/* Define to 1 if you have the `selinux' library (-lselinux). */ -+#undef HAVE_LIBSELINUX -+ - /* Define to 1 if you have the header file. */ - #undef HAVE_LINEWRAP_H - - /* Define to 1 if you have the header file. */ - #undef HAVE_LINUX_FD_H - -+/* Define to 1 if you have the `listxattr' function. */ -+#undef HAVE_LISTXATTR -+ -+/* Define to 1 if you have the `llistxattr' function. */ -+#undef HAVE_LLISTXATTR -+ - /* Define to 1 if you have the header file. */ - #undef HAVE_LOCALE_H - -@@ -486,6 +516,9 @@ - /* Define to 1 if the system has the type `long long int'. */ - #undef HAVE_LONG_LONG_INT - -+/* Define to 1 if you have the `lsetxattr' function. */ -+#undef HAVE_LSETXATTR -+ - /* Define to 1 if you have the `lstat' function. */ - #undef HAVE_LSTAT - -@@ -589,12 +622,18 @@ - /* Define to 1 if you have the header file. */ - #undef HAVE_SEARCH_H - -+/* Define to 1 if you have the header file. */ -+#undef HAVE_SELINUX_SELINUX_H -+ - /* Define to 1 if you have the `setenv' function. */ - #undef HAVE_SETENV - - /* Define to 1 if you have the `setlocale' function. */ - #undef HAVE_SETLOCALE - -+/* Define to 1 if you have the `setxattr' function. */ -+#undef HAVE_SETXATTR -+ - /* Define to 1 if you have the header file. */ - #undef HAVE_SGTTY_H - -@@ -734,6 +773,9 @@ - /* Define to 1 if you have the header file. */ - #undef HAVE_SYSEXITS_H - -+/* Define to 1 if you have the header file. */ -+#undef HAVE_SYS_ACL_H -+ - /* Define to 1 if you have the header file. */ - #undef HAVE_SYS_BITYPES_H - -@@ -891,6 +933,9 @@ - /* Define if utimes works properly. */ - #undef HAVE_WORKING_UTIMES - -+/* Define if we have a working extended attributes */ -+#undef HAVE_XATTRS -+ - /* Define to 1 if the system has the type `_Bool'. */ - #undef HAVE__BOOL - diff --git a/tar-1.19-xattrs.patch b/tar-1.19-xattrs.patch index f235577..b9d7b5c 100644 --- a/tar-1.19-xattrs.patch +++ b/tar-1.19-xattrs.patch @@ -1,6 +1,6 @@ -diff -urp tar-1.22-orig/configure.ac tar-1.22/configure.ac +diff -urNp tar-1.22-orig/configure.ac tar-1.22/configure.ac --- tar-1.22-orig/configure.ac 2009-03-05 08:01:58.000000000 +0100 -+++ tar-1.22/configure.ac 2009-03-05 09:45:42.000000000 +0100 ++++ tar-1.22/configure.ac 2009-11-23 14:48:00.000000000 +0100 @@ -40,7 +40,7 @@ AC_CHECK_HEADERS_ONCE(fcntl.h linux/fd.h sys/param.h sys/device.h sys/filio.h sys/gentape.h \ sys/inet.h sys/io/trioctl.h \ @@ -33,9 +33,9 @@ diff -urp tar-1.22-orig/configure.ac tar-1.22/configure.ac AC_CHECK_TYPE(iconv_t,:, AC_DEFINE(iconv_t, int, [Conversion descriptor type]), -diff -urp tar-1.22-orig/doc/tar.texi tar-1.22/doc/tar.texi +diff -urNp tar-1.22-orig/doc/tar.texi tar-1.22/doc/tar.texi --- tar-1.22-orig/doc/tar.texi 2009-03-05 08:04:13.000000000 +0100 -+++ tar-1.22/doc/tar.texi 2009-03-05 09:45:42.000000000 +0100 ++++ tar-1.22/doc/tar.texi 2009-11-23 14:48:00.000000000 +0100 @@ -2345,6 +2345,10 @@ Normally when creating an archive, @comm @samp{/} from member names. This option disables that behavior. @xref{absolute}. @@ -165,9 +165,9 @@ diff -urp tar-1.22-orig/doc/tar.texi tar-1.22/doc/tar.texi @end table @node Portability -diff -urp tar-1.22-orig/src/common.h tar-1.22/src/common.h +diff -urNp tar-1.22-orig/src/common.h tar-1.22/src/common.h --- tar-1.22-orig/src/common.h 2008-11-30 13:30:29.000000000 +0100 -+++ tar-1.22/src/common.h 2009-03-05 09:45:42.000000000 +0100 ++++ tar-1.22/src/common.h 2009-11-23 14:48:00.000000000 +0100 @@ -248,6 +248,15 @@ GLOBAL int same_owner_option; /* If positive, preserve permissions when extracting. */ GLOBAL int same_permissions_option; @@ -207,9 +207,9 @@ diff -urp tar-1.22-orig/src/common.h tar-1.22/src/common.h /* Module system.c */ -diff -urp tar-1.22-orig/src/create.c tar-1.22/src/create.c +diff -urNp tar-1.22-orig/src/create.c tar-1.22/src/create.c --- tar-1.22-orig/src/create.c 2008-10-30 11:58:04.000000000 +0100 -+++ tar-1.22/src/create.c 2009-03-05 09:45:42.000000000 +0100 ++++ tar-1.22/src/create.c 2009-11-23 14:48:33.000000000 +0100 @@ -24,6 +24,7 @@ #include @@ -260,9 +260,19 @@ diff -urp tar-1.22-orig/src/create.c tar-1.22/src/create.c if (is_dir) { const char *tag_file_name; -diff -urp tar-1.22-orig/src/extract.c tar-1.22/src/extract.c +@@ -1709,6 +1738,9 @@ dump_file0 (struct tar_stat_info *st, co + if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size) + write_long_link (st); + ++ xattrs_selinux_get(st, p, -1); ++ xattrs_xattrs_get(st, p, -1); ++ + block_ordinal = current_block_ordinal (); + st->stat.st_size = 0; /* force 0 size on symlink */ + header = start_header (st); +diff -urNp tar-1.22-orig/src/extract.c tar-1.22/src/extract.c --- tar-1.22-orig/src/extract.c 2008-10-30 15:10:28.000000000 +0100 -+++ tar-1.22/src/extract.c 2009-03-05 09:45:42.000000000 +0100 ++++ tar-1.22/src/extract.c 2009-11-23 14:48:33.000000000 +0100 @@ -69,6 +69,13 @@ struct delayed_set_stat mode_t invert_permissions; enum permstatus permstatus; @@ -365,12 +375,12 @@ diff -urp tar-1.22-orig/src/extract.c tar-1.22/src/extract.c p->sources->next = 0; strcpy (p->sources->string, file_name); + p->cntx_name = NULL; ++ assign_string (&p->cntx_name, current_stat_info.cntx_name); + p->acls_a_ptr = NULL; + p->acls_a_len = 0; + p->acls_d_ptr = NULL; + p->acls_d_len = 0; -+ p->xattr_map = NULL; -+ p->xattr_map_size = 0; ++ xheader_xattr_copy (¤t_stat_info, &p->xattr_map, &p->xattr_map_size); strcpy (p->target, current_stat_info.link_name); h = delayed_set_stat_head; @@ -388,10 +398,20 @@ diff -urp tar-1.22-orig/src/extract.c tar-1.22/src/extract.c set_stat (source, &st1, NULL, 0, 0, SYMTYPE); valid_source = source; } -diff -urp tar-1.22-orig/src/list.c tar-1.22/src/list.c ---- tar-1.22-orig/src/list.c 2009-03-05 09:45:15.000000000 +0100 -+++ tar-1.22/src/list.c 2009-03-05 09:45:42.000000000 +0100 -@@ -567,6 +567,13 @@ decode_header (union block *header, stru +@@ -1301,6 +1372,9 @@ apply_delayed_links (void) + sources = next; + } + ++ xheader_xattr_free (ds->xattr_map, ds->xattr_map_size); ++ free (ds->cntx_name); ++ + { + struct delayed_link *next = ds->next; + free (ds); +diff -urNp tar-1.22-orig/src/list.c tar-1.22/src/list.c +--- tar-1.22-orig/src/list.c 2009-11-23 14:47:03.000000000 +0100 ++++ tar-1.22/src/list.c 2009-11-23 14:48:00.000000000 +0100 +@@ -568,6 +568,13 @@ decode_header (union block *header, stru assign_string (&stat_info->gname, header->header.gname[0] ? header->header.gname : NULL); @@ -405,9 +425,9 @@ diff -urp tar-1.22-orig/src/list.c tar-1.22/src/list.c if (format == OLDGNU_FORMAT && incremental_option) { stat_info->atime.tv_sec = TIME_FROM_HEADER (header->oldgnu_header.atime); -diff -urp tar-1.22-orig/src/Makefile.am tar-1.22/src/Makefile.am +diff -urNp tar-1.22-orig/src/Makefile.am tar-1.22/src/Makefile.am --- tar-1.22-orig/src/Makefile.am 2007-10-29 18:53:06.000000000 +0100 -+++ tar-1.22/src/Makefile.am 2009-03-05 09:45:42.000000000 +0100 ++++ tar-1.22/src/Makefile.am 2009-11-23 14:48:00.000000000 +0100 @@ -20,7 +20,7 @@ bin_PROGRAMS = tar @@ -431,9 +451,9 @@ diff -urp tar-1.22-orig/src/Makefile.am tar-1.22/src/Makefile.am -tar_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) +tar_LDADD = $(LIBS) $(LDADD) $(LIB_CLOCK_GETTIME) -diff -urp tar-1.22-orig/src/tar.c tar-1.22/src/tar.c +diff -urNp tar-1.22-orig/src/tar.c tar-1.22/src/tar.c --- tar-1.22-orig/src/tar.c 2009-03-05 08:04:13.000000000 +0100 -+++ tar-1.22/src/tar.c 2009-03-05 09:45:42.000000000 +0100 ++++ tar-1.22/src/tar.c 2009-11-23 14:48:00.000000000 +0100 @@ -246,7 +246,8 @@ tar_set_quoting_style (char *arg) enum @@ -592,9 +612,9 @@ diff -urp tar-1.22-orig/src/tar.c tar-1.22/src/tar.c free (st->sparse_map); free (st->dumpdir); xheader_destroy (&st->xhdr); -diff -urp tar-1.22-orig/src/tar.h tar-1.22/src/tar.h +diff -urNp tar-1.22-orig/src/tar.h tar-1.22/src/tar.h --- tar-1.22-orig/src/tar.h 2007-06-27 15:30:32.000000000 +0200 -+++ tar-1.22/src/tar.h 2009-03-05 09:45:42.000000000 +0100 ++++ tar-1.22/src/tar.h 2009-11-23 14:48:00.000000000 +0100 @@ -276,6 +276,14 @@ struct xheader uintmax_t string_length; }; @@ -636,402 +656,100 @@ diff -urp tar-1.22-orig/src/tar.h tar-1.22/src/tar.h /* Extended headers */ struct xheader xhdr; -diff -urp tar-1.22-orig/src/xheader.c tar-1.22/src/xheader.c ---- tar-1.22-orig/src/xheader.c 2008-11-30 13:30:54.000000000 +0100 -+++ tar-1.22/src/xheader.c 2009-03-05 09:45:42.000000000 +0100 -@@ -417,6 +417,74 @@ xheader_write_global (struct xheader *xh - free (name); - } - -+void xheader_xattr_init(struct tar_stat_info *st) -+{ -+ st->xattr_map = NULL; -+ st->xattr_map_size = 0; -+} +diff -urNp tar-1.22-orig/src/xattrs.c tar-1.22/src/xattrs.c +--- tar-1.22-orig/src/xattrs.c 1970-01-01 01:00:00.000000000 +0100 ++++ tar-1.22/src/xattrs.c 2009-11-23 14:48:33.000000000 +0100 +@@ -0,0 +1,491 @@ ++/* Create a tar archive. + -+void xheader_xattr_free(struct xattr_array *xattr_map, size_t xattr_map_size) -+{ -+ size_t scan = 0; ++ Copyright (C) 2006 Free Software Foundation, Inc. + -+ while (scan < xattr_map_size) -+ { -+ free (xattr_map[scan].xkey); -+ free (xattr_map[scan].xval_ptr); ++ Written by James Antill, on 2006-07-27. + -+ ++scan; -+ } -+ free (xattr_map); -+} ++ This program is free software; you can redistribute it and/or modify it ++ under the terms of the GNU General Public License as published by the ++ Free Software Foundation; either version 2, or (at your option) any later ++ version. + -+static void xheader_xattr__add(struct xattr_array **xattr_map, -+ size_t *xattr_map_size, -+ const char *key, const char *val, size_t len) -+{ -+ size_t pos = (*xattr_map_size)++; -+ -+ *xattr_map = xrealloc (*xattr_map, -+ *xattr_map_size * sizeof(struct xattr_array)); -+ (*xattr_map)[pos].xkey = xstrdup (key); -+ (*xattr_map)[pos].xval_ptr = xmemdup (val, len + 1); -+ (*xattr_map)[pos].xval_len = len; -+} ++ This program is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General ++ Public License for more details. + -+void xheader_xattr_add(struct tar_stat_info *st, -+ const char *key, const char *val, size_t len) -+{ -+ size_t klen = strlen (key); -+ char *xkey = xmalloc (strlen("SCHILY.xattr.") + klen + 1); -+ char *tmp = xkey; ++ You should have received a copy of the GNU General Public License along ++ with this program; if not, write to the Free Software Foundation, Inc., ++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + -+ tmp = stpcpy (tmp, "SCHILY.xattr."); -+ tmp = stpcpy (tmp, key); -+ -+ xheader_xattr__add (&st->xattr_map, &st->xattr_map_size, xkey, val, len); ++#include + -+ free (xkey); -+} ++#include + -+void xheader_xattr_copy(const struct tar_stat_info *st, -+ struct xattr_array **xattr_map, size_t *xattr_map_size) -+{ -+ size_t scan = 0; ++#include "common.h" + -+ *xattr_map = NULL; -+ *xattr_map_size = 0; -+ -+ while (scan < st->xattr_map_size) -+ { -+ char *key = st->xattr_map[scan].xkey; -+ char *val = st->xattr_map[scan].xval_ptr; -+ size_t len = st->xattr_map[scan].xval_len; -+ -+ xheader_xattr__add(xattr_map, xattr_map_size, key, val, len); + -+ ++scan; -+ } -+} ++#ifndef HAVE_SELINUX_SELINUX_H ++# undef HAVE_LIBSELINUX ++#endif + - - /* General Interface */ - -@@ -427,6 +495,7 @@ struct xhdr_tab - struct xheader *, void const *data); - void (*decoder) (struct tar_stat_info *, char const *, char const *, size_t); - bool protect; -+ bool prefix; - }; - - /* This declaration must be extern, because ISO C99 section 6.9.2 -@@ -443,8 +512,17 @@ locate_handler (char const *keyword) - struct xhdr_tab const *p; - - for (p = xhdr_tab; p->keyword; p++) -- if (strcmp (p->keyword, keyword) == 0) -- return p; -+ if (p->prefix) -+ { -+ if (strncmp (p->keyword, keyword, strlen(p->keyword)) == 0) -+ return p; -+ } -+ else -+ { -+ if (strcmp (p->keyword, keyword) == 0) -+ return p; -+ } -+ - return NULL; - } - -@@ -454,7 +532,7 @@ xheader_protected_pattern_p (const char - struct xhdr_tab const *p; - - for (p = xhdr_tab; p->keyword; p++) -- if (p->protect && fnmatch (pattern, p->keyword, 0) == 0) -+ if (!p->prefix && p->protect && fnmatch (pattern, p->keyword, 0) == 0) - return true; - return false; - } -@@ -465,7 +543,7 @@ xheader_protected_keyword_p (const char - struct xhdr_tab const *p; - - for (p = xhdr_tab; p->keyword; p++) -- if (p->protect && strcmp (p->keyword, keyword) == 0) -+ if (!p->prefix && p->protect && strcmp (p->keyword, keyword) == 0) - return true; - return false; - } -@@ -1417,6 +1495,71 @@ volume_filename_decoder (struct tar_stat - } - - static void -+xattr_selinux_coder (struct tar_stat_info const *st, char const *keyword, -+ struct xheader *xhdr, void const *data) -+{ -+ code_string (st->cntx_name, keyword, xhdr); -+} ++#ifndef HAVE_ATTR_XATTR_H ++# undef HAVE_XATTRS ++#endif + -+static void -+xattr_selinux_decoder (struct tar_stat_info *st, -+ char const *keyword, char const *arg, size_t size) -+{ -+ decode_string (&st->cntx_name, arg); -+} ++#ifndef HAVE_SYS_ACL_H ++# undef HAVE_LIBACL ++#endif + -+static void -+xattr_acls_a_coder (struct tar_stat_info const *st , char const *keyword, -+ struct xheader *xhdr, void const *data) -+{ -+ xheader_print_n (xhdr, keyword, st->acls_a_ptr, st->acls_a_len); -+} ++#ifdef HAVE_SELINUX_SELINUX_H ++# include ++#endif + -+static void -+xattr_acls_a_decoder (struct tar_stat_info *st, -+ char const *keyword, char const *arg, size_t size) -+{ -+ st->acls_a_ptr = xmemdup (arg, size + 1); -+ st->acls_a_len = size; -+} ++#ifdef HAVE_ATTR_XATTR_H ++# include ++#endif + -+static void -+xattr_acls_d_coder (struct tar_stat_info const *st , char const *keyword, -+ struct xheader *xhdr, void const *data) -+{ -+ xheader_print_n (xhdr, keyword, st->acls_d_ptr, st->acls_d_len); -+} ++#ifdef HAVE_SYS_ACL_H ++# include ++#endif + -+static void -+xattr_acls_d_decoder (struct tar_stat_info *st, -+ char const *keyword, char const *arg, size_t size) -+{ -+ st->acls_d_ptr = xmemdup (arg, size + 1); -+ st->acls_d_len = size; -+} + -+static void -+xattr_coder (struct tar_stat_info const *st , char const *keyword, -+ struct xheader *xhdr, void const *data) ++#if 0 /* unused by xattr's atm. */ ++static void xattrs__fd_get(struct tar_stat_info *st, ++ char const *file_name, int fd, const char *attr, ++ char **ret_ptr, size_t *ret_len) +{ -+ struct xattr_array *xattr_map = st->xattr_map; -+ const size_t *off = data; -+ xheader_print_n (xhdr, keyword, -+ xattr_map[*off].xval_ptr, xattr_map[*off].xval_len); ++#ifdef HAVE_XATTRS ++ static ssize_t asz = 1024; ++ ssize_t ret = 0; ++ static char *val = NULL; ++ ++ if (!val) val = xmalloc (asz); ++ ++ while (((ret = fgetxattr (fd, attr, val, asz)) == -1) && ++ (errno == ERANGE)) ++ { ++ asz <<= 1; ++ val = xrealloc (val, asz); ++ } ++ ++ if (ret != -1) ++ { ++ *ret_ptr = xmemdup (val, ret + 1); ++ *ret_len = ret; ++ } ++ else if (errno != ENOATTR) ++ call_arg_warn ("fgetxattr", file_name); ++#endif +} ++#endif + -+static void -+xattr_decoder (struct tar_stat_info *st, -+ char const *keyword, char const *arg, size_t size) -+{ -+ char *xstr = NULL; -+ -+ xstr = xmemdup(arg, size + 1); -+ xheader_xattr_add(st, keyword + strlen("SCHILY.xattr."), xstr, size); -+ free(xstr); -+} -+ -+static void - sparse_major_coder (struct tar_stat_info const *st, char const *keyword, - struct xheader *xhdr, void const *data) - { -@@ -1453,18 +1596,18 @@ sparse_minor_decoder (struct tar_stat_in - } - - struct xhdr_tab const xhdr_tab[] = { -- { "atime", atime_coder, atime_decoder, false }, -- { "comment", dummy_coder, dummy_decoder, false }, -- { "charset", dummy_coder, dummy_decoder, false }, -- { "ctime", ctime_coder, ctime_decoder, false }, -- { "gid", gid_coder, gid_decoder, false }, -- { "gname", gname_coder, gname_decoder, false }, -- { "linkpath", linkpath_coder, linkpath_decoder, false }, -- { "mtime", mtime_coder, mtime_decoder, false }, -- { "path", path_coder, path_decoder, false }, -- { "size", size_coder, size_decoder, false }, -- { "uid", uid_coder, uid_decoder, false }, -- { "uname", uname_coder, uname_decoder, false }, -+ { "atime", atime_coder, atime_decoder, false, false }, -+ { "comment", dummy_coder, dummy_decoder, false, false }, -+ { "charset", dummy_coder, dummy_decoder, false, false }, -+ { "ctime", ctime_coder, ctime_decoder, false, false }, -+ { "gid", gid_coder, gid_decoder, false, false }, -+ { "gname", gname_coder, gname_decoder, false, false }, -+ { "linkpath", linkpath_coder, linkpath_decoder, false, false }, -+ { "mtime", mtime_coder, mtime_decoder, false, false }, -+ { "path", path_coder, path_decoder, false, false }, -+ { "size", size_coder, size_decoder, false, false }, -+ { "uid", uid_coder, uid_decoder, false, false }, -+ { "uname", uname_coder, uname_decoder, false, false }, - - /* Sparse file handling */ - { "GNU.sparse.name", path_coder, path_decoder, -@@ -1479,25 +1622,25 @@ struct xhdr_tab const xhdr_tab[] = { - true }, - - /* tar 1.14 - 1.15.90 keywords. */ -- { "GNU.sparse.size", sparse_size_coder, sparse_size_decoder, true }, -+ { "GNU.sparse.size", sparse_size_coder, sparse_size_decoder, true, false }, - /* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x' - headers, and each of them was meaningful. It confilcted with POSIX specs, - which requires that "when extended header records conflict, the last one - given in the header shall take precedence." */ - { "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder, -- true }, -+ true, false }, - { "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder, -- true }, -+ true, false }, - /* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */ - { "GNU.sparse.map", NULL /* Unused, see pax_dump_header() */, -- sparse_map_decoder, false }, -+ sparse_map_decoder, false, false }, - - { "GNU.dumpdir", dumpdir_coder, dumpdir_decoder, -- true }, -+ true, false }, - - /* Keeps the tape/volume label. May be present only in the global headers. - Equivalent to GNUTYPE_VOLHDR. */ -- { "GNU.volume.label", volume_label_coder, volume_label_decoder, true }, -+ { "GNU.volume.label", volume_label_coder, volume_label_decoder, true, false }, - - /* These may be present in a first global header of the archive. - They provide the same functionality as GNUTYPE_MULTIVOL header. -@@ -1506,9 +1649,38 @@ struct xhdr_tab const xhdr_tab[] = { - GNU.volume.offset keeps the offset of the start of this volume, - otherwise kept in oldgnu_header.offset. */ - { "GNU.volume.filename", volume_label_coder, volume_filename_decoder, -- true }, -- { "GNU.volume.size", volume_size_coder, volume_size_decoder, true }, -- { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, true }, -- -+ true, false }, -+ { "GNU.volume.size", volume_size_coder, volume_size_decoder, true, false }, -+ { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, -+ true, false }, -+ -+ /* We get the SELinux value from filecon, so add a namespace for SELinux -+ instead of storing it in SCHILY.xattr.* (which would be RAW). */ -+ { "RHT.security.selinux", -+ xattr_selinux_coder, xattr_selinux_decoder, false, false }, -+ -+ /* ACLs, use the star format... */ -+ { "SCHILY.acl.access", -+ xattr_acls_a_coder, xattr_acls_a_decoder, false, false }, -+ -+ { "SCHILY.acl.default", -+ xattr_acls_d_coder, xattr_acls_d_decoder, false, false }, -+ -+ /* FIXME: These are compat. for FC-6 ... we shipped a tar using the generic -+ header names by accident. */ -+ { "SCHILY.xattr.security.selinux", -+ xattr_selinux_coder, xattr_selinux_decoder, false, false }, -+ { "SCHILY.xattr.system.posix_acl_access", -+ xattr_acls_a_coder, xattr_acls_a_decoder, false, false }, -+ { "SCHILY.xattr.system.posix_acl_default", -+ xattr_acls_d_coder, xattr_acls_d_decoder, false, false }, -+ -+ /* xattr's, use the star format note we only save the user/trusted varients... */ -+ { "SCHILY.xattr.user", xattr_coder, xattr_decoder, false, true }, -+ { "SCHILY.xattr.trusted", xattr_coder, xattr_decoder, false, true }, -+ -+ /* ignore everything else in the xattr namespaces... */ -+ { "SCHILY.xattr", dummy_coder, dummy_decoder, false, true }, -+ - { NULL, NULL, NULL, false } - }; -diff -up /dev/null tar-1.17/src/xattrs.c ---- /dev/null 2007-12-10 11:30:31.504001819 +0100 -+++ tar-1.17/src/xattrs.c 2007-12-10 15:31:54.000000000 +0100 -@@ -0,0 +1,491 @@ -+/* Create a tar archive. -+ -+ Copyright (C) 2006 Free Software Foundation, Inc. -+ -+ Written by James Antill, on 2006-07-27. -+ -+ This program is free software; you can redistribute it and/or modify it -+ under the terms of the GNU General Public License as published by the -+ Free Software Foundation; either version 2, or (at your option) any later -+ version. -+ -+ This program is distributed in the hope that it will be useful, but -+ WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -+ Public License for more details. -+ -+ You should have received a copy of the GNU General Public License along -+ with this program; if not, write to the Free Software Foundation, Inc., -+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -+ -+#include -+ -+#include -+ -+#include "common.h" -+ -+ -+#ifndef HAVE_SELINUX_SELINUX_H -+# undef HAVE_LIBSELINUX -+#endif -+ -+#ifndef HAVE_ATTR_XATTR_H -+# undef HAVE_XATTRS -+#endif -+ -+#ifndef HAVE_SYS_ACL_H -+# undef HAVE_LIBACL -+#endif -+ -+#ifdef HAVE_SELINUX_SELINUX_H -+# include -+#endif -+ -+#ifdef HAVE_ATTR_XATTR_H -+# include -+#endif -+ -+#ifdef HAVE_SYS_ACL_H -+# include -+#endif -+ -+ -+#if 0 /* unused by xattr's atm. */ -+static void xattrs__fd_get(struct tar_stat_info *st, -+ char const *file_name, int fd, const char *attr, -+ char **ret_ptr, size_t *ret_len) -+{ -+#ifdef HAVE_XATTRS -+ static ssize_t asz = 1024; -+ ssize_t ret = 0; -+ static char *val = NULL; -+ -+ if (!val) val = xmalloc (asz); -+ -+ while (((ret = fgetxattr (fd, attr, val, asz)) == -1) && -+ (errno == ERANGE)) -+ { -+ asz <<= 1; -+ val = xrealloc (val, asz); -+ } -+ -+ if (ret != -1) -+ { -+ *ret_ptr = xmemdup (val, ret + 1); -+ *ret_len = ret; -+ } -+ else if (errno != ENOATTR) -+ call_arg_warn ("fgetxattr", file_name); -+#endif -+} -+#endif -+ -+static void xattrs__acls_get_a(struct tar_stat_info *st, -+ char const *file_name, int fd, -+ char **ret_ptr, size_t *ret_len) -+{ /* "system.posix_acl_access" */ -+#ifdef HAVE_LIBACL -+ char *val = NULL; -+ ssize_t len; -+ acl_t acl; ++static void xattrs__acls_get_a(struct tar_stat_info *st, ++ char const *file_name, int fd, ++ char **ret_ptr, size_t *ret_len) ++{ /* "system.posix_acl_access" */ ++#ifdef HAVE_LIBACL ++ char *val = NULL; ++ ssize_t len; ++ acl_t acl; + + if (fd != -1) + { @@ -1159,7 +877,7 @@ diff -up /dev/null tar-1.17/src/xattrs.c + if (!xatrs) xatrs = xmalloc (xsz); + + while (((fd == -1) ? -+ ((xret = listxattr (file_name, xatrs, xsz)) == -1) : ++ ((xret = llistxattr (file_name, xatrs, xsz)) == -1) : + ((xret = flistxattr (fd, xatrs, xsz)) == -1)) && + (errno == ERANGE)) + { @@ -1168,7 +886,7 @@ diff -up /dev/null tar-1.17/src/xattrs.c + } + + if (xret == -1) -+ call_arg_warn ((fd == -1) ? "listxattrs" : "flistxattrs", file_name); ++ call_arg_warn ((fd == -1) ? "llistxattrs" : "flistxattrs", file_name); + else + { + const char *attr = xatrs; @@ -1186,8 +904,8 @@ diff -up /dev/null tar-1.17/src/xattrs.c + strncmp (attr, "trusted.", strlen("trusted."))) + goto next_attr; /* only store normal xattrs */ + -+ while (((fd == -1) ? -+ ((aret = getxattr (file_name, attr, val, asz)) == -1) : ++ while (((fd == -1) ? ++ ((aret = lgetxattr (file_name, attr, val, asz)) == -1) : + ((aret = fgetxattr (fd, attr, val, asz)) == -1)) && + (errno == ERANGE)) + { @@ -1198,7 +916,7 @@ diff -up /dev/null tar-1.17/src/xattrs.c + if (aret != -1) + xheader_xattr_add (st, attr, val, aret); + else if (errno != ENOATTR) -+ call_arg_warn ("fgetxattr", file_name); ++ call_arg_warn ((fd==-1) ? "lgetxattr" : "fgetxattr", file_name); + + next_attr: + attr += len + 1; @@ -1433,10 +1151,9 @@ diff -up /dev/null tar-1.17/src/xattrs.c +#endif + } +} -+ -diff -up /dev/null tar-1.17/src/xattrs.h ---- /dev/null 2007-12-10 11:30:31.504001819 +0100 -+++ tar-1.17/src/xattrs.h 2007-12-10 15:31:54.000000000 +0100 +diff -urNp tar-1.22-orig/src/xattrs.h tar-1.22/src/xattrs.h +--- tar-1.22-orig/src/xattrs.h 1970-01-01 01:00:00.000000000 +0100 ++++ tar-1.22/src/xattrs.h 2009-11-23 14:48:00.000000000 +0100 @@ -0,0 +1,14 @@ + +extern void xattrs_acls_get(struct tar_stat_info *st, @@ -1452,3 +1169,305 @@ diff -up /dev/null tar-1.17/src/xattrs.h + char const *file_name, char typeflag); +extern void xattrs_xattrs_set(struct tar_stat_info const *st, + char const *file_name, char typeflag); +diff -urNp tar-1.22-orig/src/xheader.c tar-1.22/src/xheader.c +--- tar-1.22-orig/src/xheader.c 2008-11-30 13:30:54.000000000 +0100 ++++ tar-1.22/src/xheader.c 2009-11-23 14:48:00.000000000 +0100 +@@ -417,6 +417,74 @@ xheader_write_global (struct xheader *xh + free (name); + } + ++void xheader_xattr_init(struct tar_stat_info *st) ++{ ++ st->xattr_map = NULL; ++ st->xattr_map_size = 0; ++} ++ ++void xheader_xattr_free(struct xattr_array *xattr_map, size_t xattr_map_size) ++{ ++ size_t scan = 0; ++ ++ while (scan < xattr_map_size) ++ { ++ free (xattr_map[scan].xkey); ++ free (xattr_map[scan].xval_ptr); ++ ++ ++scan; ++ } ++ free (xattr_map); ++} ++ ++static void xheader_xattr__add(struct xattr_array **xattr_map, ++ size_t *xattr_map_size, ++ const char *key, const char *val, size_t len) ++{ ++ size_t pos = (*xattr_map_size)++; ++ ++ *xattr_map = xrealloc (*xattr_map, ++ *xattr_map_size * sizeof(struct xattr_array)); ++ (*xattr_map)[pos].xkey = xstrdup (key); ++ (*xattr_map)[pos].xval_ptr = xmemdup (val, len + 1); ++ (*xattr_map)[pos].xval_len = len; ++} ++ ++void xheader_xattr_add(struct tar_stat_info *st, ++ const char *key, const char *val, size_t len) ++{ ++ size_t klen = strlen (key); ++ char *xkey = xmalloc (strlen("SCHILY.xattr.") + klen + 1); ++ char *tmp = xkey; ++ ++ tmp = stpcpy (tmp, "SCHILY.xattr."); ++ tmp = stpcpy (tmp, key); ++ ++ xheader_xattr__add (&st->xattr_map, &st->xattr_map_size, xkey, val, len); ++ ++ free (xkey); ++} ++ ++void xheader_xattr_copy(const struct tar_stat_info *st, ++ struct xattr_array **xattr_map, size_t *xattr_map_size) ++{ ++ size_t scan = 0; ++ ++ *xattr_map = NULL; ++ *xattr_map_size = 0; ++ ++ while (scan < st->xattr_map_size) ++ { ++ char *key = st->xattr_map[scan].xkey; ++ char *val = st->xattr_map[scan].xval_ptr; ++ size_t len = st->xattr_map[scan].xval_len; ++ ++ xheader_xattr__add(xattr_map, xattr_map_size, key, val, len); ++ ++ ++scan; ++ } ++} ++ + + /* General Interface */ + +@@ -427,6 +495,7 @@ struct xhdr_tab + struct xheader *, void const *data); + void (*decoder) (struct tar_stat_info *, char const *, char const *, size_t); + bool protect; ++ bool prefix; + }; + + /* This declaration must be extern, because ISO C99 section 6.9.2 +@@ -443,8 +512,17 @@ locate_handler (char const *keyword) + struct xhdr_tab const *p; + + for (p = xhdr_tab; p->keyword; p++) +- if (strcmp (p->keyword, keyword) == 0) +- return p; ++ if (p->prefix) ++ { ++ if (strncmp (p->keyword, keyword, strlen(p->keyword)) == 0) ++ return p; ++ } ++ else ++ { ++ if (strcmp (p->keyword, keyword) == 0) ++ return p; ++ } ++ + return NULL; + } + +@@ -454,7 +532,7 @@ xheader_protected_pattern_p (const char + struct xhdr_tab const *p; + + for (p = xhdr_tab; p->keyword; p++) +- if (p->protect && fnmatch (pattern, p->keyword, 0) == 0) ++ if (!p->prefix && p->protect && fnmatch (pattern, p->keyword, 0) == 0) + return true; + return false; + } +@@ -465,7 +543,7 @@ xheader_protected_keyword_p (const char + struct xhdr_tab const *p; + + for (p = xhdr_tab; p->keyword; p++) +- if (p->protect && strcmp (p->keyword, keyword) == 0) ++ if (!p->prefix && p->protect && strcmp (p->keyword, keyword) == 0) + return true; + return false; + } +@@ -1417,6 +1495,71 @@ volume_filename_decoder (struct tar_stat + } + + static void ++xattr_selinux_coder (struct tar_stat_info const *st, char const *keyword, ++ struct xheader *xhdr, void const *data) ++{ ++ code_string (st->cntx_name, keyword, xhdr); ++} ++ ++static void ++xattr_selinux_decoder (struct tar_stat_info *st, ++ char const *keyword, char const *arg, size_t size) ++{ ++ decode_string (&st->cntx_name, arg); ++} ++ ++static void ++xattr_acls_a_coder (struct tar_stat_info const *st , char const *keyword, ++ struct xheader *xhdr, void const *data) ++{ ++ xheader_print_n (xhdr, keyword, st->acls_a_ptr, st->acls_a_len); ++} ++ ++static void ++xattr_acls_a_decoder (struct tar_stat_info *st, ++ char const *keyword, char const *arg, size_t size) ++{ ++ st->acls_a_ptr = xmemdup (arg, size + 1); ++ st->acls_a_len = size; ++} ++ ++static void ++xattr_acls_d_coder (struct tar_stat_info const *st , char const *keyword, ++ struct xheader *xhdr, void const *data) ++{ ++ xheader_print_n (xhdr, keyword, st->acls_d_ptr, st->acls_d_len); ++} ++ ++static void ++xattr_acls_d_decoder (struct tar_stat_info *st, ++ char const *keyword, char const *arg, size_t size) ++{ ++ st->acls_d_ptr = xmemdup (arg, size + 1); ++ st->acls_d_len = size; ++} ++ ++static void ++xattr_coder (struct tar_stat_info const *st , char const *keyword, ++ struct xheader *xhdr, void const *data) ++{ ++ struct xattr_array *xattr_map = st->xattr_map; ++ const size_t *off = data; ++ xheader_print_n (xhdr, keyword, ++ xattr_map[*off].xval_ptr, xattr_map[*off].xval_len); ++} ++ ++static void ++xattr_decoder (struct tar_stat_info *st, ++ char const *keyword, char const *arg, size_t size) ++{ ++ char *xstr = NULL; ++ ++ xstr = xmemdup(arg, size + 1); ++ xheader_xattr_add(st, keyword + strlen("SCHILY.xattr."), xstr, size); ++ free(xstr); ++} ++ ++static void + sparse_major_coder (struct tar_stat_info const *st, char const *keyword, + struct xheader *xhdr, void const *data) + { +@@ -1453,18 +1596,18 @@ sparse_minor_decoder (struct tar_stat_in + } + + struct xhdr_tab const xhdr_tab[] = { +- { "atime", atime_coder, atime_decoder, false }, +- { "comment", dummy_coder, dummy_decoder, false }, +- { "charset", dummy_coder, dummy_decoder, false }, +- { "ctime", ctime_coder, ctime_decoder, false }, +- { "gid", gid_coder, gid_decoder, false }, +- { "gname", gname_coder, gname_decoder, false }, +- { "linkpath", linkpath_coder, linkpath_decoder, false }, +- { "mtime", mtime_coder, mtime_decoder, false }, +- { "path", path_coder, path_decoder, false }, +- { "size", size_coder, size_decoder, false }, +- { "uid", uid_coder, uid_decoder, false }, +- { "uname", uname_coder, uname_decoder, false }, ++ { "atime", atime_coder, atime_decoder, false, false }, ++ { "comment", dummy_coder, dummy_decoder, false, false }, ++ { "charset", dummy_coder, dummy_decoder, false, false }, ++ { "ctime", ctime_coder, ctime_decoder, false, false }, ++ { "gid", gid_coder, gid_decoder, false, false }, ++ { "gname", gname_coder, gname_decoder, false, false }, ++ { "linkpath", linkpath_coder, linkpath_decoder, false, false }, ++ { "mtime", mtime_coder, mtime_decoder, false, false }, ++ { "path", path_coder, path_decoder, false, false }, ++ { "size", size_coder, size_decoder, false, false }, ++ { "uid", uid_coder, uid_decoder, false, false }, ++ { "uname", uname_coder, uname_decoder, false, false }, + + /* Sparse file handling */ + { "GNU.sparse.name", path_coder, path_decoder, +@@ -1479,25 +1622,25 @@ struct xhdr_tab const xhdr_tab[] = { + true }, + + /* tar 1.14 - 1.15.90 keywords. */ +- { "GNU.sparse.size", sparse_size_coder, sparse_size_decoder, true }, ++ { "GNU.sparse.size", sparse_size_coder, sparse_size_decoder, true, false }, + /* tar 1.14 - 1.15.1 keywords. Multiple instances of these appeared in 'x' + headers, and each of them was meaningful. It confilcted with POSIX specs, + which requires that "when extended header records conflict, the last one + given in the header shall take precedence." */ + { "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder, +- true }, ++ true, false }, + { "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder, +- true }, ++ true, false }, + /* tar 1.15.90 keyword, introduced to remove the above-mentioned conflict. */ + { "GNU.sparse.map", NULL /* Unused, see pax_dump_header() */, +- sparse_map_decoder, false }, ++ sparse_map_decoder, false, false }, + + { "GNU.dumpdir", dumpdir_coder, dumpdir_decoder, +- true }, ++ true, false }, + + /* Keeps the tape/volume label. May be present only in the global headers. + Equivalent to GNUTYPE_VOLHDR. */ +- { "GNU.volume.label", volume_label_coder, volume_label_decoder, true }, ++ { "GNU.volume.label", volume_label_coder, volume_label_decoder, true, false }, + + /* These may be present in a first global header of the archive. + They provide the same functionality as GNUTYPE_MULTIVOL header. +@@ -1506,9 +1649,38 @@ struct xhdr_tab const xhdr_tab[] = { + GNU.volume.offset keeps the offset of the start of this volume, + otherwise kept in oldgnu_header.offset. */ + { "GNU.volume.filename", volume_label_coder, volume_filename_decoder, +- true }, +- { "GNU.volume.size", volume_size_coder, volume_size_decoder, true }, +- { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, true }, +- ++ true, false }, ++ { "GNU.volume.size", volume_size_coder, volume_size_decoder, true, false }, ++ { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, ++ true, false }, ++ ++ /* We get the SELinux value from filecon, so add a namespace for SELinux ++ instead of storing it in SCHILY.xattr.* (which would be RAW). */ ++ { "RHT.security.selinux", ++ xattr_selinux_coder, xattr_selinux_decoder, false, false }, ++ ++ /* ACLs, use the star format... */ ++ { "SCHILY.acl.access", ++ xattr_acls_a_coder, xattr_acls_a_decoder, false, false }, ++ ++ { "SCHILY.acl.default", ++ xattr_acls_d_coder, xattr_acls_d_decoder, false, false }, ++ ++ /* FIXME: These are compat. for FC-6 ... we shipped a tar using the generic ++ header names by accident. */ ++ { "SCHILY.xattr.security.selinux", ++ xattr_selinux_coder, xattr_selinux_decoder, false, false }, ++ { "SCHILY.xattr.system.posix_acl_access", ++ xattr_acls_a_coder, xattr_acls_a_decoder, false, false }, ++ { "SCHILY.xattr.system.posix_acl_default", ++ xattr_acls_d_coder, xattr_acls_d_decoder, false, false }, ++ ++ /* xattr's, use the star format note we only save the user/trusted varients... */ ++ { "SCHILY.xattr.user", xattr_coder, xattr_decoder, false, true }, ++ { "SCHILY.xattr.trusted", xattr_coder, xattr_decoder, false, true }, ++ ++ /* ignore everything else in the xattr namespaces... */ ++ { "SCHILY.xattr", dummy_coder, dummy_decoder, false, true }, ++ + { NULL, NULL, NULL, false } + }; diff --git a/tar-1.22-exclusion-tags.patch b/tar-1.22-exclusion-tags.patch new file mode 100644 index 0000000..da2d05d --- /dev/null +++ b/tar-1.22-exclusion-tags.patch @@ -0,0 +1,59 @@ +From 6f02669c7ba8da9d9bd0592b8c4f87f399e60061 Mon Sep 17 00:00:00 2001 +From: Sergey Poznyakoff +Date: Mon, 8 Mar 2010 12:27:23 +0200 +Subject: [PATCH] Fix eventual memory override and fd exhaustion in create.c + Both bugs reported by Kamil Dudka. + +* src/create.c (check_exclusion_tags): Do not keep +pointer to a location within tagname: it may change +after xrealloc. Use byte offset instead. +(dump_file0): Close fd before returning without +dumping the directory. +--- + src/create.c | 12 +++++++----- + 1 files changed, 7 insertions(+), 5 deletions(-) + +diff --git a/src/create.c b/src/create.c +index 209e428..c69d340 100644 +--- a/src/create.c ++++ b/src/create.c +@@ -79,7 +79,7 @@ check_exclusion_tags (const char *dirname, const char **tag_file_name) + struct exclusion_tag *tag; + size_t dlen = strlen (dirname); + int addslash = dirname[dlen-1] != '/'; +- char *nptr = NULL; ++ size_t noff = 0; + + for (tag = exclusion_tags; tag; tag = tag->next) + { +@@ -90,14 +90,14 @@ check_exclusion_tags (const char *dirname, const char **tag_file_name) + tagname = xrealloc (tagname, tagsize); + } + +- if (!nptr) ++ if (noff == 0) + { + strcpy (tagname, dirname); +- nptr = tagname + dlen; ++ noff = dlen; + if (addslash) +- *nptr++ = '/'; ++ tagname[noff++] = '/'; + } +- strcpy (nptr, tag->name); ++ strcpy (tagname + noff, tag->name); + if (access (tagname, F_OK) == 0 + && (!tag->predicate || tag->predicate (tagname))) + { +@@ -1591,6 +1591,8 @@ dump_file0 (struct tar_stat_info *st, const char *p, + { + exclusion_tag_warning (st->orig_file_name, tag_file_name, + _("directory not dumped")); ++ if (fd >= 0) ++ close (fd); + return; + } + +-- +1.6.5 + diff --git a/tar-1.22-nsfraction.patch b/tar-1.22-nsfraction.patch new file mode 100644 index 0000000..2936a0b --- /dev/null +++ b/tar-1.22-nsfraction.patch @@ -0,0 +1,25 @@ +diff -urNp tar-1.22-orig/src/misc.c tar-1.22/src/misc.c +--- tar-1.22-orig/src/misc.c 2007-06-27 15:30:32.000000000 +0200 ++++ tar-1.22/src/misc.c 2010-02-04 12:05:00.000000000 +0100 +@@ -255,7 +255,20 @@ code_timespec (struct timespec t, char s + time_t s = t.tv_sec; + int ns = t.tv_nsec; + char *np; +- bool negative = s < 0; ++ bool negative; ++ ++ /* ignore any negative ns value */ ++ if (ns < 0) ++ ns = 0; ++ ++ /* ensure (ns < BILLION) to avoid SIGSEGV within code_ns_fraction () */ ++ if (BILLION <= ns ) ++ { ++ s += ns / BILLION; ++ ns %= BILLION; ++ } ++ ++ negative = s < 0; + + if (negative && ns != 0) + { diff --git a/tar-1.22-rtapelib-overflow.patch b/tar-1.22-rtapelib-overflow.patch new file mode 100644 index 0000000..295f284 --- /dev/null +++ b/tar-1.22-rtapelib-overflow.patch @@ -0,0 +1,13 @@ +diff -urNp tar-1.22-orig/lib/rtapelib.c tar-1.22/lib/rtapelib.c +--- tar-1.22-orig/lib/rtapelib.c 2007-08-12 09:57:15.000000000 +0200 ++++ tar-1.22/lib/rtapelib.c 2010-02-22 13:58:07.000000000 +0100 +@@ -573,6 +573,9 @@ rmt_read__ (int handle, char *buffer, si + || (status = get_status (handle)) == SAFE_READ_ERROR) + return SAFE_READ_ERROR; + ++ if (status > length) ++ return SAFE_READ_ERROR; ++ + for (counter = 0; counter < status; counter += rlen, buffer += rlen) + { + rlen = safe_read (READ_SIDE (handle), buffer, status - counter); diff --git a/tar-1.22-utimens.patch b/tar-1.22-utimens.patch new file mode 100644 index 0000000..3b12c5b --- /dev/null +++ b/tar-1.22-utimens.patch @@ -0,0 +1,29 @@ +diff -urNp tar-1.22-orig/lib/utimens.c tar-1.22/lib/utimens.c +--- tar-1.22-orig/lib/utimens.c 2008-10-30 08:57:49.000000000 +0100 ++++ tar-1.22/lib/utimens.c 2010-01-05 20:14:50.348792138 +0100 +@@ -120,16 +120,17 @@ gl_futimens (int fd ATTRIBUTE_UNUSED, + } + #endif + #if HAVE_FUTIMENS +- { +- int result = futimens (fd, timespec); ++ if (0 <= fd) ++ { ++ int result = futimens (fd, timespec); + # ifdef __linux__ +- /* Work around the same bug as above. */ +- if (0 < result) +- errno = ENOSYS; ++ /* Work around the same bug as above. */ ++ if (0 < result) ++ errno = ENOSYS; + # endif +- if (result == 0 || errno != ENOSYS) +- return result; +- } ++ if (result == 0 || errno != ENOSYS) ++ return result; ++ } + #endif + + /* The platform lacks an interface to set file timestamps with diff --git a/tar-1.22-xheaderleak.patch b/tar-1.22-xheaderleak.patch new file mode 100644 index 0000000..22e1615 --- /dev/null +++ b/tar-1.22-xheaderleak.patch @@ -0,0 +1,11 @@ +diff -urNp tar-1.22-orig/src/xheader.c tar-1.22/src/xheader.c +--- tar-1.22-orig/src/xheader.c 2009-11-23 15:29:22.000000000 +0100 ++++ tar-1.22/src/xheader.c 2009-11-23 15:30:55.000000000 +0100 +@@ -722,7 +722,6 @@ xheader_read (struct xheader *xhdr, unio + { + size_t j = 0; + +- xheader_init (xhdr); + size += BLOCKSIZE; + xhdr->size = size; + xhdr->buffer = xmalloc (size + 1); diff --git a/tar.1 b/tar.1 index ee890bf..4f3efb6 100644 --- a/tar.1 +++ b/tar.1 @@ -1,675 +1,591 @@ -.TH TAR 1 "Oct 2004" "GNU" "tar" +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.35. +.TH TAR "1" "November 2009" "tar 1.22" "User Commands" .SH NAME -tar \- The GNU version of the tar archiving utility +tar \- manual page for tar 1.22 .SH SYNOPSIS .B tar -.I [options] - -.I Operations: -.nf -.B [-]A --catenate --concatenate -.B [-]c --create -.B [-]d --diff --compare -.B [-]r --append -.B [-]t --list -.B [-]u --update -.B [-]x --extract --get -.B --delete -.fi - -.I Common Options: -.nf -.B -C, --directory DIR -.B -f, --file F -.B -j, --bzip2 -.B -p, --preserve-permissions -.B -v, --verbose -.B -z, --gzip -.fi - -.I All Options: -.br -[ -.B --atime-preserve -] -[ -.B -b, --blocking-factor N -] -[ -.B -B, --read-full-records -] -[ -.B --backup BACKUP-TYPE -] -[ -.B --block-compress -] -[ -.B -C, --directory DIR -] -[ -.B -l, --check-links -] -[ -.B --checkpoint -] -[ -.B -f, --file [HOSTNAME:]F -] -[ -.B -F, --info-script F --new-volume-script F -] -[ -.B --force-local -] -[ -.B --format FORMAT -] -[ -.B -g, --listed-incremental F -] -[ -.B -G, --incremental -] -[ -.B --group GROUP -] -[ -.B -h, --dereference -] -[ -.B --help -] -[ -.B -i, --ignore-zeros -] -[ -.B --ignore-case -] -[ -.B --ignore-failed-read -] -[ -.B --index-file FILE -] -[ -.B -j, --bzip2 -] -[ -.B -k, --keep-old-files -] -[ -.B -K, --starting-file F -] -[ -.B --keep-newer-files -] -[ -.B --one-file-system -] -[ -.B -L, --tape-length N -] -[ -.B -m, --touch, --modification-time -] -[ -.B -M, --multi-volume -] -[ -.B --mode PERMISSIONS -] -[ -.B -N, --after-date DATE, --newer DATE -] -[ -.B --newer-mtime DATE -] -[ -.B --no-anchored -] -[ -.B --no-ignore-case -] -[ -.B --no-recursion -] -[ -.B --no-same-permissions -] -[ -.B --no-wildcards -] -[ -.B --no-wildcards-match-slash -] -[ -.B --null -] -[ -.B --numeric-owner -] -[ -.B -o, --old-archive, --portability, --no-same-owner -] -[ -.B -O, --to-stdout -] -[ -.B --occurrence[=NUM] -] -[ -.B --overwrite -] -[ -.B --overwrite-dir -] -[ -.B --owner USER -] -[ -.B -p, --same-permissions, --preserve-permissions -] -[ -.B -P, --absolute-names -] -[ -.B --pax-option KEYWORD-LIST -] -[ -.B --posix -] -[ -.B --preserve -] -[ -.B --acls -] -[ -.B --selinux -] -[ -.B --xattrs -] -[ -.B --no-acls -] -[ -.B --no-selinux -] -[ -.B --no-xattrs -] -[ -.B -R, --block-number -] -[ -.B --record-size SIZE -] -[ -.B --recursion -] -[ -.B --recursive-unlink -] -[ -.B --remove-files -] -[ -.B --rmt-command CMD -] -[ -.B --rsh-command CMD -] -[ -.B -s, --same-order, --preserve-order -] -[ -.B -S, --sparse -] -[ -.B --same-owner -] -[ -.B --show-defaults -] -[ -.B --show-omitted-dirs -] -[ -.B --strip-components NUMBER, --strip-path NUMBER (1) -] -[ -.B --suffix SUFFIX -] -[ -.B -T, --files-from F -] -[ -.B --totals -] -[ -.B -U, --unlink-first -] -[ -.B --use-compress-program PROG -] -[ -.B --utc -] -[ -.B -v, --verbose -] -[ -.B -V, --label NAME -] -[ -.B --version -] -[ -.B --volno-file F -] -[ -.B -w, --interactive, --confirmation -] -[ -.B -W, --verify -] -[ -.B --wildcards -] -[ -.B --wildcards-match-slash -] -[ -.B --exclude PATTERN -] -[ -.B -X, --exclude-from FILE -] -[ -.B -Z, --compress, --uncompress -] -[ -.B -z, --gzip, --gunzip, --ungzip -] -[ -.B -[0-7][lmh] -] - -(1) tar-1.14 uses --strip-path, tar-1.14.90+ uses --strip-components +[\fIOPTION\fR...] [\fIFILE\fR]... .SH DESCRIPTION -This manual page documents the GNU version of \fBtar\fR, an archiving -program designed to store and extract files from an archive file known -as a \fItarfile\fR. A \fItarfile\fR may be made on a tape drive, -however, it is also common to write a \fItarfile\fR to a normal file. -The first argument to \fBtar\fR must be one of the options \fBAcdrtux\fR, -followed by any optional functions. The final arguments to \fBtar\fR -are the names of the files or directories which should be archived. The -use of a directory name always implies that the subdirectories below -should be included in the archive. +GNU `tar' saves many files together into a single tape or disk archive, and can +restore individual files from the archive. .SH EXAMPLES .TP -.B tar -xvf foo.tar -verbosely extract foo.tar -.TP -.B tar -xzf foo.tar.gz -extract gzipped foo.tar.gz -.TP -.B tar -cjf foo.tar.bz2 bar/ -create bzipped tar archive of the directory bar called foo.tar.bz2 +tar \fB\-cf\fR archive.tar foo bar +# Create archive.tar from files foo and bar. .TP -.B tar -xjf foo.tar.bz2 -C bar/ -extract bzipped foo.tar.bz2 after changing directory to bar +tar \fB\-tvf\fR archive.tar +# List all files in archive.tar verbosely. .TP -.B tar -xzf foo.tar.gz blah.txt -extract the file blah.txt from foo.tar.gz -.SH "FUNCTION LETTERS" -.TP -.B One of the following options must be used: +tar \fB\-xf\fR archive.tar +# Extract all files from archive.tar. +.IP +.SH OPTIONS +.SH Main operation mode: .TP -.B -A, --catenate, --concatenate +\fB\-A\fR, \fB\-\-catenate\fR, \fB\-\-concatenate\fR append tar files to an archive .TP -.B -c, --create +\fB\-c\fR, \fB\-\-create\fR create a new archive .TP -.B -d, --diff, --compare +\fB\-d\fR, \fB\-\-diff\fR, \fB\-\-compare\fR find differences between archive and file system .TP -.B -r, --append +\fB\-\-delete\fR +delete from the archive (not on mag tapes!) +.TP +\fB\-r\fR, \fB\-\-append\fR append files to the end of an archive .TP -.B -t, --list +\fB\-t\fR, \fB\-\-list\fR list the contents of an archive .TP -.B -u, --update -only append files that are newer than the existing in archive +\fB\-\-test\-label\fR +test the archive volume label and exit .TP -.B -x, --extract, --get -extract files from an archive +\fB\-u\fR, \fB\-\-update\fR +only append files newer than copy in archive .TP -.B --delete -delete from the archive (not for use on mag tapes!) -.SH "COMMON OPTIONS" +\fB\-x\fR, \fB\-\-extract\fR, \fB\-\-get\fR +extract files from an archive +.IP + +.SH\fBCommon Options:\fR .TP -.B -C, --directory DIR +\fB-C\fR, \fB--directory=DIR\fR change to directory DIR .TP -.B -f, --file [HOSTNAME:]F -Use archive file or device F (default "-", meaning stdin/stdout). -Note that "/dev/stdout" is not equivalent to "-". Using "/dev/stdout" -explicitly can lead to corrupted archive, especially when coupled with "-v". +\fB-f\fR, \fB--file=ARCHIVE\fR +use archive file or device ARCHIVE +.TP +\fB-j\fR, \fB--bzip2\fR +filter the archive through bzip2 .TP -.B -j, --bzip2 -filter archive through bzip2, use to decompress .bz2 files +\fB -J\fR, \fB--xz\fR +filter the archive through xz .TP -.B -p, --preserve-permissions -extract all protection information +\fB-p\fR, \fB--preserve-permissions\fR +extract information about file permissions (default for superuser) .TP -.B -v, --verbose +\fB-v\fR, \fB--verbose\fR verbosely list files processed .TP -.B -z, --gzip, --ungzip +\fB-z\fR, \fB--gzip\fR filter the archive through gzip -.SH "ALL OPTIONS" + +.SH Operation modifiers: .TP -.B --atime-preserve -don't change access times on dumped files +\fB\-\-check\-device\fR +check device numbers when creating incremental +archives (default) .TP -.B -b, --blocking-factor N -block size of Nx512 bytes (default N=20) +\fB\-g\fR, \fB\-\-listed\-incremental\fR=\fIFILE\fR +handle new GNU\-format incremental backup .TP -.B -B, --read-full-blocks -reblock as we read (for reading 4.2BSD pipes) +\fB\-G\fR, \fB\-\-incremental\fR +handle old GNU\-format incremental backup .TP -.B --backup BACKUP-TYPE -backup files instead of deleting them using BACKUP-TYPE simple or -numbered +\fB\-\-ignore\-failed\-read\fR +do not exit with nonzero on unreadable files .TP -.B --block-compress -block the output of compression program for tapes +\fB\-n\fR, \fB\-\-seek\fR +archive is seekable .TP -.B -C, --directory DIR -change to directory DIR +\fB\-\-no\-check\-device\fR +do not check device numbers when creating +incremental archives .TP -.B -l, --check-links -warn if number of hard links to the file on the filesystem mismatch the -number of links recorded in the archive +\fB\-\-occurrence\fR[=\fINUMBER\fR] +process only the NUMBERth occurrence of each file +in the archive; this option is valid only in +conjunction with one of the subcommands \fB\-\-delete\fR, +\fB\-\-diff\fR, \fB\-\-extract\fR or \fB\-\-list\fR and when a list of +files is given either on the command line or via +the \fB\-T\fR option; NUMBER defaults to 1 .TP -.B --checkpoint -print directory names while reading the archive +\fB\-\-sparse\-version\fR=\fIMAJOR[\fR.MINOR] +set version of the sparse format to use (implies +\fB\-\-sparse\fR) .TP -.B -f, --file [HOSTNAME:]F -Use archive file or device F (default "-", meaning stdin/stdout). -Note that "/dev/stdout" is not equivalent to "-". Using "/dev/stdout" -explicitly can lead to corrupted archive, especially when coupled with "-v". +\fB\-S\fR, \fB\-\-sparse\fR +handle sparse files efficiently +.IP +.SH Overwrite control: .TP -.B -F, --info-script F --new-volume-script F -run script at end of each tape (implies \fI--multi-volume\fR) +\fB\-k\fR, \fB\-\-keep\-old\-files\fR +don't replace existing files when extracting .TP -.B --force-local -archive file is local even if has a colon +\fB\-\-keep\-newer\-files\fR +don't replace existing files that are newer than +their archive copies .TP -.B --format FORMAT -selects output archive format -.nf -\fIv7\fR - Unix V7 -\fIoldgnu\fR - GNU tar <=1.12 -\fIgnu\fR - GNU tar 1.13 -\fIustar\fR - POSIX.1-1988 -\fIposix\fR - POSIX.1-2001 -.fi +\fB\-\-no\-overwrite\-dir\fR +preserve metadata of existing directories .TP -.B -g, --listed-incremental F -create/list/extract new GNU-format incremental backup +\fB\-\-overwrite\fR +overwrite existing files when extracting .TP -.B -G, --incremental -create/list/extract old GNU-format incremental backup +\fB\-\-overwrite\-dir\fR +overwrite metadata of existing directories when +extracting (default) .TP -.B -h, --dereference -don't dump symlinks; dump the files they point to +\fB\-\-recursive\-unlink\fR +empty hierarchies prior to extracting directory .TP -.B --help -like this manpage, but not as cool +\fB\-\-remove\-files\fR +remove files after adding them to the archive .TP -.B -i, --ignore-zeros -ignore blocks of zeros in archive (normally mean EOF) +\fB\-U\fR, \fB\-\-unlink\-first\fR +remove each file prior to extracting over it .TP -.B --ignore-case -ignore case when excluding files +\fB\-W\fR, \fB\-\-verify\fR +attempt to verify the archive after writing it +.IP +.SH Select output stream: +.HP +\fB\-\-ignore\-command\-error\fR ignore exit codes of children +.TP +\fB\-\-no\-ignore\-command\-error\fR +treat non\-zero exit codes of children as +error .TP -.B --ignore-failed-read -don't exit with non-zero status on unreadable files +\fB\-O\fR, \fB\-\-to\-stdout\fR +extract files to standard output .TP -.B --index-file FILE -send verbose output to FILE instead of stdout +\fB\-\-to\-command\fR=\fICOMMAND\fR +pipe extracted files to another program +.IP +Handling of file attributes: .TP -.B -j, --bzip2 -filter archive through bzip2, use to decompress .bz2 files +\fB\-\-acls\fR +Save the ACLs to the archive .TP -.B -k, --keep-old-files -keep existing files; don't overwrite them from archive +\fB\-\-atime\-preserve\fR[=\fIMETHOD\fR] +preserve access times on dumped files, either +by restoring the times after reading +(METHOD='replace'; default) or by not setting the +times in the first place (METHOD='system') .TP -.B -K, --starting-file F -begin at file F in the archive +\fB\-\-delay\-directory\-restore\fR +delay setting modification times and +permissions of extracted directories until the end +of extraction .TP -.B --keep-newer-files -do not overwrite files which are newer than the archive +\fB\-\-group\fR=\fINAME\fR +force NAME as group for added files .TP -.B --one-file-system -stay in local file system when creating an archive +\fB\-\-mode\fR=\fICHANGES\fR +force (symbolic) mode CHANGES for added files .TP -.B -L, --tape-length N -change tapes after writing N*1024 bytes +\fB\-\-mtime\fR=\fIDATE\-OR\-FILE\fR +set mtime for added files from DATE\-OR\-FILE .TP -.B -m, --touch, --modification-time +\fB\-m\fR, \fB\-\-touch\fR don't extract file modified time .TP -.B -M, --multi-volume -create/list/extract multi-volume archive +\fB\-\-no\-acls\fR +Don't extract the ACLs from the archive +.TP +\fB\-\-no\-delay\-directory\-restore\fR +cancel the effect of \fB\-\-delay\-directory\-restore\fR +option .TP -.B --mode PERMISSIONS -apply PERMISSIONS while adding files (see \fBchmod\fR(1)) +\fB\-\-no\-same\-owner\fR +extract files as yourself .TP -.B -N, --after-date DATE, --newer DATE -only store files newer than DATE +\fB\-\-no\-same\-permissions\fR +apply the user's umask when extracting permissions +from the archive (default for ordinary users) .TP -.B --newer-mtime DATE -like \fI--newer\fR, but with a DATE +\fB\-\-no\-selinux\fR +Don't extract the SELinux context from the archive .TP -.B --no-anchored -match any subsequenceof the name's components with \fI--exclude\fR +\fB\-\-no\-xattrs\fR +Don't extract the user/root xattrs from the +archive .TP -.B --no-ignore-case -use case-sensitive matching with \fI--exclude\fR +\fB\-\-numeric\-owner\fR +always use numbers for user/group names .TP -.B --no-recursion -don't recurse into directories +\fB\-\-owner\fR=\fINAME\fR +force NAME as owner for added files .TP -.B --no-same-permissions -apply user's umask when extracting files instead of recorded permissions +\fB\-p\fR, \fB\-\-preserve\-permissions\fR, \fB\-\-same\-permissions\fR +extract information about file permissions +(default for superuser) .TP -.B --no-wildcards -don't use wildcards with \fI--exclude\fR +\fB\-\-preserve\fR +same as both \fB\-p\fR and \fB\-s\fR .TP -.B --no-wildcards-match-slash -wildcards do not match slashes (/) with \fI--exclude\fR +\fB\-\-same\-owner\fR +try extracting files with the same ownership .TP -.B --null -\fI--files-from\fR reads null-terminated names, disable \fI--directory\fR +\fB\-s\fR, \fB\-\-preserve\-order\fR, \fB\-\-same\-order\fR +sort names to extract to match archive .TP -.B --numeric-owner -always use numbers for user/group names +\fB\-\-selinux\fR +Save the SELinux context to the archive .TP -.B -o, --old-archive, --portability -like \fI--format=v7\fR; \fI-o\fR exhibits this behavior when creating an -archive (deprecated behavior) +\fB\-\-xattrs\fR +Save the user/root xattrs to the archive +.IP +.SH Device selection and switching: .TP -.B -o, --no-same-owner -do not attempt to restore ownership when extracting; \fI-o\fR exhibits -this behavior when extracting an archive +\fB\-f\fR, \fB\-\-file\fR=\fIARCHIVE\fR +use archive file or device ARCHIVE .TP -.B -O, --to-stdout -extract files to standard output +\fB\-\-force\-local\fR +archive file is local even if it has a colon .TP -.B --occurrence[=NUM] -process only the NUMth occurrence of each named file; used with -\fI--delete\fR, \fI--diff\fR, \fI--extract\fR, or \fI--list\fR. -NUM defaults to 1. +\fB\-F\fR, \fB\-\-info\-script\fR=\fINAME\fR, \fB\-\-new\-volume\-script\fR=\fINAME\fR +run script at end of each tape (implies \fB\-M\fR) .TP -.B --overwrite -overwrite existing files and directory metadata when extracting +\fB\-L\fR, \fB\-\-tape\-length\fR=\fINUMBER\fR +change tape after writing NUMBER x 1024 bytes .TP -.B --overwrite-dir -overwrite directory metadata when extracting +\fB\-M\fR, \fB\-\-multi\-volume\fR +create/list/extract multi\-volume archive .TP -.B --owner USER -change owner of extraced files to USER +\fB\-\-rmt\-command\fR=\fICOMMAND\fR +use given rmt COMMAND instead of rmt .TP -.B -p, --same-permissions, --preserve-permissions -extract all protection information +\fB\-\-rsh\-command\fR=\fICOMMAND\fR +use remote COMMAND instead of rsh .TP -.B -P, --absolute-names -don't strip leading `/'s from file names +\fB\-\-volno\-file\fR=\fIFILE\fR +use/update the volume number in FILE +.IP +.SH Device blocking: .TP -.B --pax-option KEYWORD-LIST -used only with POSIX.1-2001 archives to modify the way \fBtar\fR handles -extended header keywords +\fB\-b\fR, \fB\-\-blocking\-factor\fR=\fIBLOCKS\fR +BLOCKS x 512 bytes per record .TP -.B --posix -like \fI--format=posix\fR +\fB\-B\fR, \fB\-\-read\-full\-records\fR +reblock as we read (for 4.2BSD pipes) .TP -.B --preserve -like \fI--preserve-permissions\fR \fI--same-order\fR +\fB\-i\fR, \fB\-\-ignore\-zeros\fR +ignore zeroed blocks in archive (means EOF) .TP -.B --acls -this option causes \fBtar\fR to store each file's ACLs in the archive. +\fB\-\-record\-size\fR=\fINUMBER\fR +NUMBER of bytes per record, multiple of 512 +.IP +.SH Archive format selection: .TP -.B --selinux -this option causes \fBtar\fR to store each file's SELinux security context information in the archive. +\fB\-H\fR, \fB\-\-format\fR=\fIFORMAT\fR +create archive of the given format +.IP +FORMAT is one of the following: .TP -.B --xattrs -this option causes \fBtar\fR to store each file's extended attributes in the archive. This option also enables \fI--acls\fR and\fI--selinux\fR if they haven't been set already, due to the fact that the data for those are stored in special xattrs. +gnu +GNU tar 1.13.x format .TP -.B --no-acls -This option causes \fBtar\fR not to store each file's ACLs in the archive and not to extract any ACL information in an archive. +oldgnu +GNU format as per tar <= 1.12 .TP -.B --no-selinux -this option causes \fBtar\fR not to store each file's SELinux security context information in the archive and not to extract any SELinux information in an archive. +pax +POSIX 1003.1\-2001 (pax) format .TP -.B --no-xattrs -this option causes \fBtar\fR not to store each file's extended attributes in the archive and not to extract any extended attributes in an archive. This option also enables \fI--no-acls\fR and \fI--no-selinux\fR if they haven't been set already. +posix +same as pax .TP -.B -R, --record-number -show record number within archive with each message +ustar +POSIX 1003.1\-1988 (ustar) format .TP -.B --record-size SIZE -use SIZE bytes per record when accessing archives +v7 +old V7 tar format .TP -.B --recursion -recurse into directories +\fB\-\-old\-archive\fR, \fB\-\-portability\fR +same as \fB\-\-format\fR=\fIv7\fR .TP -.B --recursive-unlink -remove existing directories before extracting directories of the same name +\fB\-\-pax\-option\fR=\fIkeyword[[\fR:]=value][,keyword[[:]=value]]... +control pax keywords .TP -.B --remove-files -remove files after adding them to the archive +\fB\-\-posix\fR +same as \fB\-\-format\fR=\fIposix\fR .TP -.B --rmt-command CMD -use CMD instead of the default /usr/sbin/rmt +\fB\-V\fR, \fB\-\-label\fR=\fITEXT\fR +create archive with volume name TEXT; at +list/extract time, use TEXT as a globbing pattern +for volume name +.IP +\fBCompression options:\fR .TP -.B --rsh-command CMD -use remote CMD instead of \fBrsh\fR(1) +\fB\-a\fR, \fB\-\-auto\-compress\fR +use archive suffix to determine the compression +program .TP -.B -s, --same-order, --preserve-order -list of names to extract is sorted to match archive +\fB\-I\fR, \fB\-\-use\-compress\-program\fR=\fIPROG\fR +filter through PROG (must accept \fB\-d\fR) .TP -.B -S, --sparse -handle sparse files efficiently +\fB\-j\fR, \fB\-\-bzip2\fR +filter the archive through bzip2 .TP -.B --same-owner -create extracted files with the same ownership +\fB\-\-lzma\fR +filter the archive through lzma .TP -.B --show-defaults -display the default options used by \fBtar\fR +\fB\-\-no\-auto\-compress\fR +do not use archive suffix to determine the +compression program .TP -.B --show-omitted-dirs -print directories \fBtar\fR skips while operating on an archive +\fB\-z\fR, \fB\-\-gzip\fR, \fB\-\-gunzip\fR, \fB\-\-ungzip\fR +filter the archive through gzip .TP -.B --strip-components NUMBER, --strip-path NUMBER -strip NUMBER of leading components from file names before extraction - -(1) tar-1.14 uses --strip-path, tar-1.14.90+ uses --strip-components +\fB\-Z\fR, \fB\-\-compress\fR, \fB\-\-uncompress\fR +filter the archive through compress .TP -.B --suffix SUFFIX -use SUFFIX instead of default '~' when backing up files +\fB\-J\fR, \fB\-\-xz\fR +filter the archive through xz .TP -.B -T, --files-from F -get names to extract or create from file F +\fB\-\-lzop\fR +filter the archive through lzop +.IP +.SH Local file selection: .TP -.B --totals -print total bytes written with --create +\fB\-\-add\-file\fR=\fIFILE\fR +add given FILE to the archive (useful if its name +starts with a dash) .TP -.B -U, --unlink-first -remove existing files before extracting files of the same name +\fB\-\-backup\fR[=\fICONTROL\fR] +backup before removal, choose version CONTROL .TP -.B --use-compress-program PROG -access the archive through PROG which is generally a compression program +\fB\-C\fR, \fB\-\-directory\fR=\fIDIR\fR +change to directory DIR .TP -.B --utc -display file modification dates in UTC +\fB\-\-exclude\fR=\fIPATTERN\fR +exclude files, given as a PATTERN .TP -.B -v, --verbose -verbosely list files processed +\fB\-\-exclude\-caches\fR +exclude contents of directories containing +CACHEDIR.TAG, except for the tag file itself +.TP +\fB\-\-exclude\-caches\-all\fR +exclude directories containing CACHEDIR.TAG +.TP +\fB\-\-exclude\-caches\-under\fR exclude everything under directories containing +CACHEDIR.TAG +.TP +\fB\-\-exclude\-tag\fR=\fIFILE\fR +exclude contents of directories containing FILE, +except for FILE itself +.HP +\fB\-\-exclude\-tag\-all\fR=\fIFILE\fR exclude directories containing FILE +.TP +\fB\-\-exclude\-tag\-under\fR=\fIFILE\fR +exclude everything under directories +containing FILE +.TP +\fB\-\-exclude\-vcs\fR +exclude version control system directories +.TP +\fB\-h\fR, \fB\-\-dereference\fR +follow symlinks; archive and dump the files they +point to +.TP +\fB\-\-hard\-dereference\fR +follow hard links; archive and dump the files they +refer to +.TP +\fB\-K\fR, \fB\-\-starting\-file\fR=\fIMEMBER\-NAME\fR +begin at member MEMBER\-NAME in the archive +.TP +\fB\-\-newer\-mtime\fR=\fIDATE\fR +compare date and time when data changed only .TP -.B -V, --label NAME -create archive with volume name NAME +\fB\-\-no\-null\fR +disable the effect of the previous \fB\-\-null\fR option .TP -.B --version -print \fBtar\fR program version number +\fB\-\-no\-recursion\fR +avoid descending automatically in directories .TP -.B --volno-file F -keep track of which volume of a multi-volume archive its working in -FILE; used with \fI--multi-volume\fR +\fB\-\-no\-unquote\fR +do not unquote filenames read with \fB\-T\fR +.HP +\fB\-\-null\fR \fB\-T\fR reads null\-terminated names, disable \fB\-C\fR .TP -.B -w, --interactive, --confirmation +\fB\-N\fR, \fB\-\-newer\fR=\fIDATE\-OR\-FILE\fR, \fB\-\-after\-date\fR=\fIDATE\-OR\-FILE\fR +only store files newer than DATE\-OR\-FILE +.TP +\fB\-\-one\-file\-system\fR +stay in local file system when creating archive +.TP +\fB\-P\fR, \fB\-\-absolute\-names\fR +don't strip leading `/'s from file names +.TP +\fB\-\-recursion\fR +recurse into directories (default) +.TP +\fB\-\-suffix\fR=\fISTRING\fR +backup before removal, override usual suffix ('~' +unless overridden by environment variable +SIMPLE_BACKUP_SUFFIX) +.TP +\fB\-T\fR, \fB\-\-files\-from\fR=\fIFILE\fR +get names to extract or create from FILE +.TP +\fB\-\-unquote\fR +unquote filenames read with \fB\-T\fR (default) +.TP +\fB\-X\fR, \fB\-\-exclude\-from\fR=\fIFILE\fR +exclude patterns listed in FILE +.IP +.SH File name transformations: +.TP +\fB\-\-strip\-components\fR=\fINUMBER\fR +strip NUMBER leading components from file +names on extraction +.TP +\fB\-\-transform\fR=\fIEXPRESSION\fR, \fB\-\-xform\fR=\fIEXPRESSION\fR +use sed replace EXPRESSION to transform file +names +.IP +File name matching options (affect both exclude and include patterns): +.TP +\fB\-\-anchored\fR +patterns match file name start +.TP +\fB\-\-ignore\-case\fR +ignore case +.TP +\fB\-\-no\-anchored\fR +patterns match after any `/' (default for +exclusion) +.TP +\fB\-\-no\-ignore\-case\fR +case sensitive matching (default) +.TP +\fB\-\-no\-wildcards\fR +verbatim string matching +.TP +\fB\-\-no\-wildcards\-match\-slash\fR +wildcards do not match `/' +.TP +\fB\-\-wildcards\fR +use wildcards (default) +.TP +\fB\-\-wildcards\-match\-slash\fR +wildcards match `/' (default for exclusion) +.IP +Informative output: +.TP +\fB\-\-checkpoint\fR[=\fINUMBER\fR] +display progress messages every NUMBERth record +(default 10) +.TP +\fB\-\-checkpoint\-action\fR=\fIACTION\fR +execute ACTION on each checkpoint +.TP +\fB\-\-index\-file\fR=\fIFILE\fR +send verbose output to FILE +.TP +\fB\-l\fR, \fB\-\-check\-links\fR +print a message if not all links are dumped +.TP +\fB\-\-no\-quote\-chars\fR=\fISTRING\fR +disable quoting for characters from STRING +.TP +\fB\-\-quote\-chars\fR=\fISTRING\fR +additionally quote characters from STRING +.TP +\fB\-\-quoting\-style\fR=\fISTYLE\fR +set name quoting style; see below for valid STYLE +values +.TP +\fB\-R\fR, \fB\-\-block\-number\fR +show block number within archive with each +message +.TP +\fB\-\-show\-defaults\fR +show tar defaults +.TP +\fB\-\-show\-omitted\-dirs\fR +when listing or extracting, list each directory +that does not match search criteria +.TP +\fB\-\-show\-transformed\-names\fR, \fB\-\-show\-stored\-names\fR +show file or archive names after transformation +.TP +\fB\-\-totals\fR[=\fISIGNAL\fR] +print total bytes after processing the archive; +with an argument \- print total bytes when this +SIGNAL is delivered; Allowed signals are: SIGHUP, +SIGQUIT, SIGINT, SIGUSR1 and SIGUSR2; the names +without SIG prefix are also accepted +.TP +\fB\-\-utc\fR +print file modification dates in UTC +.TP +\fB\-v\fR, \fB\-\-verbose\fR +verbosely list files processed +.TP +\fB\-w\fR, \fB\-\-interactive\fR, \fB\-\-confirmation\fR ask for confirmation for every action +.IP + +.SH Compatibility options: .TP -.B -W, --verify -attempt to verify the archive after writing it +\fB\-o\fR +when creating, same as \fB\-\-old\-archive\fR; when +extracting, same as \fB\-\-no\-same\-owner\fR +.IP + +.SH Other options: .TP -.B --wildcards -use wildcards with \fI--exclude\fR +\-?, \fB\-\-help\fR +give this help list .TP -.B --wildcards-match-slash -wildcards match slashes (/) with \fI--exclude\fR +\fB\-\-restrict\fR +disable use of some potentially harmful options .TP -.B --exclude PATTERN -exclude files based upon PATTERN +\fB\-\-usage\fR +give a short usage message .TP -.B -X, --exclude-from FILE -exclude files listed in FILE +\fB\-\-version\fR +print program version +.PP +.PP +Mandatory or optional arguments to long options are also mandatory or optional +for any corresponding short options. +.PP +The backup suffix is `~', unless set with \fB\-\-suffix\fR or SIMPLE_BACKUP_SUFFIX. +The version control may be set with \fB\-\-backup\fR or VERSION_CONTROL, values are: .TP -.B -Z, --compress, --uncompress -filter the archive through compress +none, off +never make backups .TP -.B -z, --gzip, --gunzip, --ungzip -filter the archive through gzip +t, numbered +make numbered backups +.TP +nil, existing +numbered if numbered backups exist, simple otherwise .TP -.B --use-compress-program PROG -filter the archive through PROG (which must accept -d) -.TP -.B -[0-7][lmh] -specify drive and density -.SH BUGS -The GNU folks, in general, abhor man pages, and create info documents instead. -The maintainer of \fBtar\fR falls into this category. Thus this man page may -not be complete, nor current, and was included in the Red Hat CVS tree -because man is a great tool :). This man page was first taken from Debian -Linux and has since been loving updated here. +never, simple +always make simple backups +.PP +Valid arguments for \fB\-\-quoting\-style\fR options are: +.IP +literal +shell +shell\-always +c +c\-maybe +escape +locale +clocale +.PP +.SH DEFAULTS +*This* tar defaults to: +\fB\-\-format\fR=\fIgnu\fR \fB\-f\-\fR \fB\-b20\fR \fB\-\-quoting\-style\fR=\fIescape\fR \fB\-\-rmt\-command=\fR/sbin/rmt +\fB\-\-rsh\-command=\fR/usr/bin/rsh +.SH AUTHOR +Written by John Gilmore and Jay Fenlason. .SH "REPORTING BUGS" -Please report bugs via https://bugzilla.redhat.com +Report bugs to . +.SH COPYRIGHT +Copyright \(co 2009 Free Software Foundation, Inc. +License GPLv3+: GNU GPL version 3 or later . +.br +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. .SH "SEE ALSO" The full documentation for .B tar @@ -682,8 +598,3 @@ programs are properly installed at your site, the command .B info tar .PP should give you access to the complete manual. -.SH "AUTHORS" -.nf -Debian Linux http://www.debian.org/ -Mike Frysinger -.fi diff --git a/tar.spec b/tar.spec index b57a0f3..9727a45 100644 --- a/tar.spec +++ b/tar.spec @@ -2,21 +2,44 @@ Summary: A GNU file archiving program Name: tar Epoch: 2 Version: 1.22 -Release: 4%{?dist} +Release: 5%{?dist} License: GPLv3+ Group: Applications/Archiving URL: http://www.gnu.org/software/tar/ Source0: ftp://ftp.gnu.org/pub/gnu/tar/tar-%{version}.tar.bz2 Source1: ftp://ftp.gnu.org/pub/gnu/tar/tar-%{version}.tar.bz2.sig +#Manpage for tar and gtar, a bit modified help2man generated manpage Source2: tar.1 +#Stop issuing lone zero block warnings Patch1: tar-1.14-loneZeroWarning.patch +#Fix extracting sparse files to a filesystem like vfat, +#when ftruncate may fail to grow the size of a file.(#179507) Patch2: tar-1.15.1-vfatTruncate.patch +#Add support for selinux, acl and extended attributes Patch3: tar-1.19-xattrs.patch -Patch4: tar-1.19-xattrs-conf.patch -Patch5: tar-1.17-wildcards.patch -Patch6: tar-1.22-atime-rofs.patch -Patch7: tar-1.22-shortreadbuffer.patch -Patch8: tar-1.22-fortifysourcessigabrt.patch +#change inclusion defaults of tar to "--wildcards --anchored +#--wildcards-match-slash" for compatibility reasons (#206841) +Patch4: tar-1.17-wildcards.patch +#ignore errors from setting utime() for source file +#on read-only filesystem (#500742) +Patch5: tar-1.22-atime-rofs.patch +#Report record size only if the archive refers to a device(#487760) +Patch6: tar-1.22-shortreadbuffer.patch +#Do not sigabrt with new gcc/glibc because of writing to +#struct members of gnutar header at once via strcpy +Patch7: tar-1.22-fortifysourcessigabrt.patch +#fix memory leak in xheader (#518079) +Patch8: tar-1.22-xheaderleak.patch +#fix segfault in code_ns_fraction() with corrupted metadata (#531441) +Patch9: tar-1.22-nsfraction.patch +#update gnulib's utimens module to latest version to prevent utimens() bad file +#descriptor failures with POSIX2008 glibc +Patch10: tar-1.22-utimens.patch +#Fix potential place for overflow attack via rsh/ssh (#572149) +Patch11: tar-1.22-rtapelib-overflow.patch +#realloc within check_exclusion_tags() causes invalid write(#570591) +Patch12: tar-1.22-exclusion-tags.patch + Prereq: info BuildRequires: autoconf automake gzip texinfo gettext libacl-devel libselinux-devel gawk rsh Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -40,12 +63,15 @@ the rmt package. %patch1 -p1 -b .loneZeroWarning %patch2 -p1 -b .vfatTruncate %patch3 -p1 -b .xattrs -%patch4 -p1 -b .xattrs-conf -%patch5 -p1 -b .wildcards -%patch6 -p1 -b .rofs -%patch7 -p1 -b .shortread -%patch8 -p1 -b .headerblackmagic - +%patch4 -p1 -b .wildcards +%patch5 -p1 -b .rofs +%patch6 -p1 -b .shortread +%patch7 -p1 -b .headerblackmagic +%patch8 -p1 -b .xheaderleak +%patch9 -p1 -b .nsfraction +%patch10 -p1 -b .utimens +%patch11 -p1 -b .overflow +%patch12 -p1 -b .exclude %build autoreconf @@ -60,6 +86,7 @@ ln -s tar ${RPM_BUILD_ROOT}/bin/gtar rm -f $RPM_BUILD_ROOT/%{_infodir}/dir mkdir -p ${RPM_BUILD_ROOT}%{_mandir}/man1 install -c -p -m 0644 %{SOURCE2} ${RPM_BUILD_ROOT}%{_mandir}/man1 +ln -s tar.1.gz ${RPM_BUILD_ROOT}%{_mandir}/man1/gtar.1 # XXX Nuke unpackaged files. rm -f ${RPM_BUILD_ROOT}/sbin/rmt @@ -74,11 +101,15 @@ make check rm -rf ${RPM_BUILD_ROOT} %post -/sbin/install-info %{_infodir}/tar.info.gz %{_infodir}/dir || : +if [ -f %{_infodir}/tar.info.gz ]; then + /sbin/install-info %{_infodir}/tar.info.gz %{_infodir}/dir || : +fi %preun if [ $1 = 0 ]; then - /sbin/install-info --delete %{_infodir}/tar.info.gz %{_infodir}/dir || : + if [ -f %{_infodir}/tar.info.gz ]; then + /sbin/install-info --delete %{_infodir}/tar.info.gz %{_infodir}/dir || : + fi fi %files -f %{name}.lang @@ -88,6 +119,7 @@ fi /bin/tar /bin/gtar %{_mandir}/man1/tar.1* +%{_mandir}/man1/gtar.1* %else %{_bindir}/* %{_libexecdir}/* @@ -97,6 +129,25 @@ fi %{_infodir}/tar.info* %changelog +* Wed Mar 10 2010 Ondrej Vasik 2:1.22-5 +- CVE-2010-0624 tar, cpio: Heap-based buffer overflow + by expanding a specially-crafted archive (#572149) +- realloc within check_exclusion_tags() caused invalid write + (#570591) +- not closing file descriptors for excluded files/dirs with + exlude-tag... options could cause descriptor exhaustion + (#570591) +- do not fail with POSIX 2008 glibc futimens() (#552320) +- fix segfault with corrupted metadata in code_ns_fraction + (#531441) +- commented patches and sources +- store xattrs for symlinks (#525992) - by Kamil Dudka +- update tar(1) manpage (#539787) +- fix memory leak in xheader (#518079) +- store SELinux context for symlinks (#525992) +- provide symlink manpage for gtar +- do process install-info only without --excludedocs(#515923) + * Thu Jul 16 2009 Ondrej Vasik 2:1.22-4 - Fix restoring of directory default acls(#511145) - Do not patch generated autotools files