]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
copy: fix SELinux context preservation for existing directories
authorPádraig Brady <P@draigBrady.com>
Thu, 2 Jan 2014 16:40:58 +0000 (16:40 +0000)
committerPádraig Brady <P@draigBrady.com>
Mon, 13 Jan 2014 12:52:26 +0000 (12:52 +0000)
* src/copy.c (copy_internal): Use the global process context
to set the context of existing directories before they're populated.
This is more consistent with the new directory case, and fixes
a bug for existing directories where we erroneously set the
context to the last copied descendent, rather than to that of
the source directory itself.
* tests/cp/cp-a-selinux.sh: Add a test for this case.
* NEWS: Mention the fix.
* THANKS.in: Add reporter Michal Trunecka.

NEWS
THANKS.in
src/copy.c
tests/cp/cp-a-selinux.sh

diff --git a/NEWS b/NEWS
index 66884db743aafe55aaad4dcbec984644e9bffecf..3e1f9c6ac60ae2a9fb40b872eaca58c9f08c6be6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,13 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** Bug fixes
+
+  cp -a, mv, and install --preserve-context, once again set the correct SELinux
+  context for existing directories in the destination.  Previously they set
+  the context of an existing directory to that of its last copied descendent.
+  [bug introduced in coreutils-8.22]
+
 
 * Noteworthy changes in release 8.22 (2013-12-13) [stable]
 
index 658837601379e7508c3e29a3e962205479d937c7..5b3e96ed2476097faa8da77773398e6b6f6179c8 100644 (file)
--- a/THANKS.in
+++ b/THANKS.in
@@ -441,6 +441,7 @@ Michael Veksler                     mveksler@techunix.technion.ac.il
 Michail Litvak                      mci@owl.openwall.com
 Michal Politowski                   mpol@charybda.icm.edu.pl
 Michal Svec                         msvec@suse.cz
+Michal Trunecka                     mtruneck@redhat.com
 Michel Robitaille                   robitail@IRO.UMontreal.CA
 Michiel Bacchiani                   bacchian@raven.bu.edu
 Mike Castle                         dalgoda@ix.netcom.com
index 557d37b2b9540f57c1a48d7a7320b37835089d41..3e4cbff7f4badac4f5da736ae844066981f071d4 100644 (file)
@@ -2408,6 +2408,17 @@ copy_internal (char const *src_name, char const *dst_name,
       else
         {
           omitted_permissions = 0;
+
+          /* For directories, the process global context could be reset for
+             descendents, so use it to set the context for existing dirs here.
+             This will also give earlier indication of failure to set ctx.  */
+          if (x->set_security_context || x->preserve_security_context)
+            if (! set_file_security_ctx (dst_name, x->preserve_security_context,
+                                         false, x))
+              {
+                if (x->require_preserve_context)
+                  goto un_backup;
+              }
         }
 
       /* Decide whether to copy the contents of the directory.  */
@@ -2598,7 +2609,7 @@ copy_internal (char const *src_name, char const *dst_name,
 
   /* With -Z or --preserve=context, set the context for existing files.
      Note this is done already for copy_reg() for reasons described therein.  */
-  if (!new_dst && !x->copy_as_regular
+  if (!new_dst && !x->copy_as_regular && !S_ISDIR (src_mode)
       && (x->set_security_context || x->preserve_security_context))
     {
       if (! set_file_security_ctx (dst_name, x->preserve_security_context,
index 79b1c0acf5852d1b9ab357124df3709f57c4c531..3ab7e0e287589920163af95cf6689316971fd8bb 100755 (executable)
@@ -41,6 +41,22 @@ test -s err && fail=1   #there must be no stderr output for -a
 ls -Z e | grep $ctx || fail=1
 ls -Z f | grep $ctx || fail=1
 
+# Check handling of existing dirs which requires specific handling
+# due to recursion, and was handled incorrectly in coreutils-8.22
+# Note standard permissions are updated for existing directories
+# in the destination, so SELinux contexts should be updated too.
+chmod o+rw restore/existing_dir
+mkdir -p backup/existing_dir/ || framework_failure_
+ls -Zd backup/existing_dir | grep $ctx && framework_failure_
+touch backup/existing_dir/file || framework_failure_
+chcon $ctx backup/existing_dir/file || framework_failure_
+# Set the dir context to ensure it is reset
+mkdir -p --context="$ctx" restore/existing_dir || framework_failure_
+# Copy and ensure existing directories updated
+cp -a backup/. restore/
+ls -Zd restore/existing_dir | grep $ctx &&
+  { ls -lZd restore/existing_dir; fail=1; }
+
 # Check restorecon (-Z) functionality for file and directory
 get_selinux_type() { ls -Zd "$1" | sed -n 's/.*:\(.*_t\):.*/\1/p'; }
 # Also make a dir with our known context