restore basic functionality of --acl, --selinux, and --xattr (#717684)

This commit is contained in:
Kamil Dudka 2011-09-26 16:34:29 +02:00
parent fc7e71a489
commit bf72587fee
3 changed files with 166 additions and 30 deletions

View File

@ -0,0 +1,111 @@
From fd137d96707d776fb2541e3d362825bb650dc786 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdudka@redhat.com>
Date: Mon, 26 Sep 2011 15:36:13 +0200
Subject: [PATCH 2/2] misc: partially revert upstream commit 4bde4f3
---
src/misc.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 50 insertions(+), 1 deletions(-)
diff --git a/src/misc.c b/src/misc.c
index b75f2ab..a6e5294 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -21,6 +21,7 @@
#include <rmt.h>
#include "common.h"
#include <quotearg.h>
+#include <save-cwd.h>
#include <xgetcwd.h>
#include <unlinkdir.h>
#include <utimens.h>
@@ -633,6 +634,14 @@ struct wd
/* The directory's name. */
char const *name;
+ /* A negative value if no attempt has been made to save the
+ directory, 0 if it was saved successfully, and a positive errno
+ value if it was not saved successfully. */
+ int err;
+
+ /* The saved version of the directory, if ERR == 0. */
+ struct saved_cwd saved_cwd;
+
/* If nonzero, the file descriptor of the directory, or AT_FDCWD if
the working directory. If zero, the directory needs to be opened
to be used. */
@@ -687,6 +696,7 @@ chdir_arg (char const *dir)
if (! wd_count)
{
wd[wd_count].name = ".";
+ wd[wd_count].err = -1;
wd[wd_count].fd = AT_FDCWD;
wd_count++;
}
@@ -704,6 +714,7 @@ chdir_arg (char const *dir)
}
wd[wd_count].name = dir;
+ wd[wd_count].err = -1;
wd[wd_count].fd = 0;
return wd_count++;
}
@@ -728,9 +739,44 @@ chdir_do (int i)
if (chdir_current != i)
{
struct wd *curr = &wd[i];
+ struct wd *prev = &wd[chdir_current];
int fd = curr->fd;
- if (! fd)
+ if (prev->err < 0)
+ {
+ prev->err = 0;
+ if (save_cwd (&prev->saved_cwd) != 0)
+ prev->err = errno;
+ else if (0 <= prev->saved_cwd.desc)
+ {
+ /* Make sure we still have at least one descriptor available. */
+ int fd1 = prev->saved_cwd.desc;
+ int fd2 = dup (fd1);
+ if (0 <= fd2)
+ close (fd2);
+ else if (errno == EMFILE)
+ {
+ /* Force restore_cwd to use chdir_long. */
+ close (fd1);
+ prev->saved_cwd.desc = -1;
+ prev->saved_cwd.name = xgetcwd ();
+ if (! prev->saved_cwd.name)
+ prev->err = errno;
+ }
+ else
+ prev->err = errno;
+ }
+ }
+
+ if (0 <= curr->err)
+ {
+ int err = curr->err;
+ if (err == 0 && restore_cwd (&curr->saved_cwd) != 0)
+ err = errno;
+ if (err)
+ FATAL_ERROR ((0, err, _("Cannot restore working directory")));
+ }
+ else if (! fd)
{
if (! IS_ABSOLUTE_FILE_NAME (curr->name))
chdir_do (i - 1);
@@ -741,6 +787,9 @@ chdir_do (int i)
curr->fd = fd;
+ if (chdir (curr->name) != 0)
+ chdir_fatal (curr->name);
+
/* Add I to the cache, tossing out the lowest-ranking entry if the
cache is full. */
if (wdcache_count < CHDIR_CACHE_SIZE)
--
1.7.4.4

View File

@ -1,3 +1,17 @@
configure.ac | 20 ++-
doc/tar.texi | 75 +++++++++
src/Makefile.am | 7 +-
src/common.h | 18 ++
src/create.c | 54 ++++++-
src/extract.c | 123 ++++++++++++++
src/list.c | 7 +
src/tar.c | 80 +++++++++-
src/tar.h | 20 +++
src/xattrs.c | 489 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/xattrs.h | 14 ++
src/xheader.c | 237 +++++++++++++++++++++++----
12 files changed, 1103 insertions(+), 41 deletions(-)
diff -urNp tar-1.24-orig/configure.ac tar-1.24/configure.ac diff -urNp tar-1.24-orig/configure.ac tar-1.24/configure.ac
--- tar-1.24-orig/configure.ac 2010-10-24 23:35:35.000000000 +0200 --- tar-1.24-orig/configure.ac 2010-10-24 23:35:35.000000000 +0200
+++ tar-1.24/configure.ac 2010-10-25 10:24:52.548214037 +0200 +++ tar-1.24/configure.ac 2010-10-25 10:24:52.548214037 +0200
@ -63,7 +77,7 @@ diff -urNp tar-1.24-orig/doc/tar.texi tar-1.24/doc/tar.texi
@opsummary{after-date} @opsummary{after-date}
@item --after-date @item --after-date
@@ -2915,6 +2919,10 @@ contents have changed (as opposed to jus @@ -2914,6 +2918,10 @@ contents have changed (as opposed to just @option{--newer}, which will
also back up files for which any status information has also back up files for which any status information has
changed). @xref{after}. changed). @xref{after}.
@ -74,7 +88,7 @@ diff -urNp tar-1.24-orig/doc/tar.texi tar-1.24/doc/tar.texi
@opsummary{no-anchored} @opsummary{no-anchored}
@item --no-anchored @item --no-anchored
An exclude pattern can match any subsequence of the name's components. An exclude pattern can match any subsequence of the name's components.
@@ -2998,11 +3006,21 @@ locations. Usually @command{tar} determ @@ -2997,11 +3005,21 @@ locations. Usually @command{tar} determines automatically whether
the archive can be seeked or not. Use this option to disable this the archive can be seeked or not. Use this option to disable this
mechanism. mechanism.
@ -96,7 +110,7 @@ diff -urNp tar-1.24-orig/doc/tar.texi tar-1.24/doc/tar.texi
@opsummary{no-wildcards} @opsummary{no-wildcards}
@item --no-wildcards @item --no-wildcards
Do not use wildcards. Do not use wildcards.
@@ -3235,6 +3253,11 @@ in cases when such recognition fails. I @@ -3234,6 +3252,11 @@ in cases when such recognition fails. It takes effect only if the
archive is open for reading (e.g. with @option{--list} or archive is open for reading (e.g. with @option{--list} or
@option{--extract} options). @option{--extract} options).
@ -108,7 +122,7 @@ diff -urNp tar-1.24-orig/doc/tar.texi tar-1.24/doc/tar.texi
@opsummary{show-defaults} @opsummary{show-defaults}
@item --show-defaults @item --show-defaults
@@ -3448,6 +3471,11 @@ Enable or disable warning messages ident @@ -3447,6 +3470,11 @@ Enable or disable warning messages identified by @var{keyword}. The
messages are suppressed if @var{keyword} is prefixed with @samp{no-}. messages are suppressed if @var{keyword} is prefixed with @samp{no-}.
@xref{warnings}. @xref{warnings}.
@ -120,7 +134,7 @@ diff -urNp tar-1.24-orig/doc/tar.texi tar-1.24/doc/tar.texi
@opsummary{wildcards} @opsummary{wildcards}
@item --wildcards @item --wildcards
Use wildcards when matching member names with patterns. Use wildcards when matching member names with patterns.
@@ -8643,6 +8671,8 @@ implementation able to read @samp{ustar} @@ -8659,6 +8687,8 @@ implementation able to read @samp{ustar} archives will be able to read
most @samp{posix} archives as well, with the only exception that any most @samp{posix} archives as well, with the only exception that any
additional information (such as long file names etc.) will in such additional information (such as long file names etc.) will in such
case be extracted as plain text files along with the files it refers to. case be extracted as plain text files along with the files it refers to.
@ -129,7 +143,7 @@ diff -urNp tar-1.24-orig/doc/tar.texi tar-1.24/doc/tar.texi
This archive format will be the default format for future versions This archive format will be the default format for future versions
of @GNUTAR{}. of @GNUTAR{}.
@@ -9259,6 +9289,51 @@ Same as both @option{--same-permissions} @@ -9293,6 +9323,51 @@ Same as both @option{--same-permissions} and @option{--same-order}.
This option is deprecated, and will be removed in @GNUTAR{} version 1.23. This option is deprecated, and will be removed in @GNUTAR{} version 1.23.
@ -200,7 +214,7 @@ diff -urNp tar-1.24-orig/src/common.h tar-1.24/src/common.h
/* When set, strip the given number of file name components from the file name /* When set, strip the given number of file name components from the file name
before extracting */ before extracting */
GLOBAL size_t strip_name_components; GLOBAL size_t strip_name_components;
@@ -706,6 +715,9 @@ extern char *output_start; @@ -707,6 +716,9 @@ extern char *output_start;
void update_archive (void); void update_archive (void);
@ -210,7 +224,7 @@ diff -urNp tar-1.24-orig/src/common.h tar-1.24/src/common.h
/* Module xheader.c. */ /* Module xheader.c. */
void xheader_decode (struct tar_stat_info *stat); void xheader_decode (struct tar_stat_info *stat);
@@ -726,6 +738,12 @@ bool xheader_string_end (struct xheader @@ -727,6 +739,12 @@ bool xheader_string_end (struct xheader *xhdr, char const *keyword);
bool xheader_keyword_deleted_p (const char *kw); bool xheader_keyword_deleted_p (const char *kw);
char *xheader_format_name (struct tar_stat_info *st, const char *fmt, char *xheader_format_name (struct tar_stat_info *st, const char *fmt,
size_t n); size_t n);
@ -234,7 +248,7 @@ diff -urNp tar-1.24-orig/src/create.c tar-1.24/src/create.c
#include <hash.h> #include <hash.h>
/* Error number to use when an impostor is discovered. /* Error number to use when an impostor is discovered.
@@ -934,6 +935,30 @@ start_header (struct tar_stat_info *st) @@ -936,6 +937,30 @@ start_header (struct tar_stat_info *st)
GNAME_TO_CHARS (st->gname, header->header.gname); GNAME_TO_CHARS (st->gname, header->header.gname);
} }
@ -265,18 +279,22 @@ diff -urNp tar-1.24-orig/src/create.c tar-1.24/src/create.c
return header; return header;
} }
@@ -1709,6 +1734,10 @@ dump_file0 (struct tar_stat_info *st, ch @@ -1710,6 +1735,14 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
{
bool ok; bool ok;
struct stat final_stat; struct stat final_stat;
+ int fd_xattr = fd;
+ xattrs_acls_get(st, p, fd, !is_dir); + if (!fd_xattr)
+ xattrs_selinux_get(st, p, fd); + // upstream tar now uses zero fd as "no fd"
+ xattrs_xattrs_get(st, p, fd); + fd_xattr = -1;
+ +
+ xattrs_acls_get(st, p, fd_xattr, !is_dir);
+ xattrs_selinux_get(st, p, fd_xattr);
+ xattrs_xattrs_get(st, p, fd_xattr);
if (is_dir) if (is_dir)
{ {
const char *tag_file_name; @@ -1829,6 +1862,9 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
@@ -1826,6 +1855,9 @@ dump_file0 (struct tar_stat_info *st, ch
if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size) if (NAME_FIELD_SIZE - (archive_format == OLDGNU_FORMAT) < size)
write_long_link (st); write_long_link (st);
@ -286,7 +304,7 @@ diff -urNp tar-1.24-orig/src/create.c tar-1.24/src/create.c
block_ordinal = current_block_ordinal (); block_ordinal = current_block_ordinal ();
st->stat.st_size = 0; /* force 0 size on symlink */ st->stat.st_size = 0; /* force 0 size on symlink */
header = start_header (st); header = start_header (st);
@@ -1844,11 +1876,23 @@ dump_file0 (struct tar_stat_info *st, ch @@ -1847,11 +1883,23 @@ dump_file0 (struct tar_stat_info *st, char const *name, char const *p)
} }
#endif #endif
else if (S_ISCHR (st->stat.st_mode)) else if (S_ISCHR (st->stat.st_mode))
@ -398,7 +416,7 @@ diff -urNp tar-1.24-orig/src/extract.c tar-1.24/src/extract.c
strcpy (data->file_name, file_name); strcpy (data->file_name, file_name);
delayed_set_stat_head = data; delayed_set_stat_head = data;
if (must_be_dot_or_slash (file_name)) if (must_be_dot_or_slash (file_name))
@@ -661,6 +708,31 @@ maybe_recoverable (char *file_name, bool @@ -673,6 +727,31 @@ maybe_recoverable (char *file_name, bool regular, bool *interdir_made)
return RECOVER_NO; return RECOVER_NO;
} }
@ -430,7 +448,7 @@ diff -urNp tar-1.24-orig/src/extract.c tar-1.24/src/extract.c
/* Fix the statuses of all directories whose statuses need fixing, and /* Fix the statuses of all directories whose statuses need fixing, and
which are not ancestors of FILE_NAME. If AFTER_LINKS is which are not ancestors of FILE_NAME. If AFTER_LINKS is
nonzero, do this for all such directories; otherwise, stop at the nonzero, do this for all such directories; otherwise, stop at the
@@ -721,12 +793,23 @@ apply_nonancestor_delayed_set_stat (char @@ -733,12 +812,23 @@ apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
sb.stat.st_gid = data->gid; sb.stat.st_gid = data->gid;
sb.atime = data->atime; sb.atime = data->atime;
sb.mtime = data->mtime; sb.mtime = data->mtime;
@ -454,7 +472,7 @@ diff -urNp tar-1.24-orig/src/extract.c tar-1.24/src/extract.c
free (data); free (data);
} }
} }
@@ -842,6 +925,7 @@ extract_dir (char *file_name, int typefl @@ -854,6 +944,7 @@ extract_dir (char *file_name, int typeflag)
static int static int
open_output_file (char const *file_name, int typeflag, mode_t mode, open_output_file (char const *file_name, int typeflag, mode_t mode,
@ -462,7 +480,7 @@ diff -urNp tar-1.24-orig/src/extract.c tar-1.24/src/extract.c
mode_t *current_mode, mode_t *current_mode_mask) mode_t *current_mode, mode_t *current_mode_mask)
{ {
int fd; int fd;
@@ -852,6 +936,10 @@ open_output_file (char const *file_name, @@ -864,6 +955,10 @@ open_output_file (char const *file_name, int typeflag, mode_t mode,
? O_TRUNC | (dereference_option ? 0 : O_NOFOLLOW) ? O_TRUNC | (dereference_option ? 0 : O_NOFOLLOW)
: O_EXCL)); : O_EXCL));
@ -473,7 +491,7 @@ diff -urNp tar-1.24-orig/src/extract.c tar-1.24/src/extract.c
if (typeflag == CONTTYPE) if (typeflag == CONTTYPE)
{ {
static int conttype_diagnosed; static int conttype_diagnosed;
@@ -908,6 +996,7 @@ extract_file (char *file_name, int typef @@ -934,6 +1029,7 @@ extract_file (char *file_name, int typeflag)
bool interdir_made = false; bool interdir_made = false;
mode_t mode = (current_stat_info.stat.st_mode & MODE_RWX mode_t mode = (current_stat_info.stat.st_mode & MODE_RWX
& ~ (0 < same_owner_option ? S_IRWXG | S_IRWXO : 0)); & ~ (0 < same_owner_option ? S_IRWXG | S_IRWXO : 0));
@ -481,7 +499,7 @@ diff -urNp tar-1.24-orig/src/extract.c tar-1.24/src/extract.c
mode_t current_mode = 0; mode_t current_mode = 0;
mode_t current_mode_mask = 0; mode_t current_mode_mask = 0;
@@ -924,7 +1013,17 @@ extract_file (char *file_name, int typef @@ -950,7 +1046,17 @@ extract_file (char *file_name, int typeflag)
} }
else else
{ {
@ -499,7 +517,7 @@ diff -urNp tar-1.24-orig/src/extract.c tar-1.24/src/extract.c
&current_mode, &current_mode_mask)) &current_mode, &current_mode_mask))
< 0) < 0)
{ {
@@ -1065,6 +1164,13 @@ create_placeholder_file (char *file_name @@ -1091,6 +1197,13 @@ create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
+ strlen (file_name) + 1); + strlen (file_name) + 1);
p->sources->next = 0; p->sources->next = 0;
strcpy (p->sources->string, file_name); strcpy (p->sources->string, file_name);
@ -513,7 +531,7 @@ diff -urNp tar-1.24-orig/src/extract.c tar-1.24/src/extract.c
strcpy (p->target, current_stat_info.link_name); strcpy (p->target, current_stat_info.link_name);
h = delayed_set_stat_head; h = delayed_set_stat_head;
@@ -1499,6 +1605,13 @@ apply_delayed_links (void) @@ -1525,6 +1638,13 @@ apply_delayed_links (void)
st1.stat.st_gid = ds->gid; st1.stat.st_gid = ds->gid;
st1.atime = ds->atime; st1.atime = ds->atime;
st1.mtime = ds->mtime; st1.mtime = ds->mtime;
@ -527,7 +545,7 @@ diff -urNp tar-1.24-orig/src/extract.c tar-1.24/src/extract.c
set_stat (source, &st1, -1, 0, 0, SYMTYPE, set_stat (source, &st1, -1, 0, 0, SYMTYPE,
false, AT_SYMLINK_NOFOLLOW); false, AT_SYMLINK_NOFOLLOW);
valid_source = source; valid_source = source;
@@ -1513,6 +1626,9 @@ apply_delayed_links (void) @@ -1539,6 +1659,9 @@ apply_delayed_links (void)
sources = next; sources = next;
} }
@ -540,7 +558,7 @@ diff -urNp tar-1.24-orig/src/extract.c tar-1.24/src/extract.c
diff -urNp tar-1.24-orig/src/list.c tar-1.24/src/list.c diff -urNp tar-1.24-orig/src/list.c tar-1.24/src/list.c
--- tar-1.24-orig/src/list.c 2010-10-25 09:15:14.216463863 +0200 --- tar-1.24-orig/src/list.c 2010-10-25 09:15:14.216463863 +0200
+++ tar-1.24/src/list.c 2010-10-25 10:24:52.563213968 +0200 +++ tar-1.24/src/list.c 2010-10-25 10:24:52.563213968 +0200
@@ -597,6 +597,13 @@ decode_header (union block *header, stru @@ -615,6 +615,13 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
assign_string (&stat_info->gname, assign_string (&stat_info->gname,
header->header.gname[0] ? header->header.gname : NULL); header->header.gname[0] ? header->header.gname : NULL);
@ -1580,6 +1598,8 @@ diff -urNp tar-1.24-orig/src/xheader.c tar-1.24/src/xheader.c
+ XHDR_PROTECTED | XHDR_GLOBAL, false }, + XHDR_PROTECTED | XHDR_GLOBAL, false },
{ "GNU.volume.offset", volume_offset_coder, volume_offset_decoder, { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder,
- XHDR_PROTECTED | XHDR_GLOBAL }, - XHDR_PROTECTED | XHDR_GLOBAL },
-
- { NULL, NULL, NULL, 0 }
+ XHDR_PROTECTED | XHDR_GLOBAL, false }, + XHDR_PROTECTED | XHDR_GLOBAL, false },
+ +
+ /* We get the SELinux value from filecon, so add a namespace for SELinux + /* We get the SELinux value from filecon, so add a namespace for SELinux
@ -1611,7 +1631,6 @@ diff -urNp tar-1.24-orig/src/xheader.c tar-1.24/src/xheader.c
+ +
+ /* ignore everything else in the xattr namespaces... */ + /* ignore everything else in the xattr namespaces... */
+ { "SCHILY.xattr", dummy_coder, dummy_decoder, 0, true }, + { "SCHILY.xattr", dummy_coder, dummy_decoder, 0, true },
+
- { NULL, NULL, NULL, 0 }
+ { NULL, NULL, NULL, 0, false } + { NULL, NULL, NULL, 0, false }
}; };

View File

@ -5,7 +5,7 @@ Summary: A GNU file archiving program
Name: tar Name: tar
Epoch: 2 Epoch: 2
Version: 1.26 Version: 1.26
Release: 1%{?dist} Release: 2%{?dist}
License: GPLv3+ License: GPLv3+
Group: Applications/Archiving Group: Applications/Archiving
URL: http://www.gnu.org/software/tar/ URL: http://www.gnu.org/software/tar/
@ -30,6 +30,8 @@ Patch5: tar-1.22-atime-rofs.patch
Patch6: tar-1.23-oldarchive.patch Patch6: tar-1.23-oldarchive.patch
#temporarily disable sigpipe.at patch (fails at build in koji, passes manually) #temporarily disable sigpipe.at patch (fails at build in koji, passes manually)
Patch7: tar-sigpipe.patch Patch7: tar-sigpipe.patch
#partially revert upstream commit 4bde4f3 (#717684)
Patch8: tar-1.24-openat-partial-revert.patch
BuildRequires: autoconf automake gzip texinfo gettext libacl-devel gawk rsh BuildRequires: autoconf automake gzip texinfo gettext libacl-devel gawk rsh
%if %{WITH_SELINUX} %if %{WITH_SELINUX}
BuildRequires: libselinux-devel BuildRequires: libselinux-devel
@ -59,6 +61,7 @@ the rmt package.
%patch5 -p1 -b .rofs %patch5 -p1 -b .rofs
%patch6 -p1 -b .oldarchive %patch6 -p1 -b .oldarchive
%patch7 -p1 -b .fail %patch7 -p1 -b .fail
%patch8 -p1 -b .openat
autoreconf autoreconf
@ -120,6 +123,9 @@ fi
%{_infodir}/tar.info* %{_infodir}/tar.info*
%changelog %changelog
* Mon Sep 26 2011 Kamil Dudka <kdudka@redhat.com> 2:1.26-2
- restore basic functionality of --acl, --selinux, and --xattr (#717684)
* Sat Mar 12 2011 Ondrej Vasik <ovasik@redhat.com> 2:1.26-1 * Sat Mar 12 2011 Ondrej Vasik <ovasik@redhat.com> 2:1.26-1
- new upstream release 1.26 - new upstream release 1.26
* Wed Feb 09 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2:1.25-6 * Wed Feb 09 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2:1.25-6