coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] copy: fix SELinux context preservation for existing directories


From: Pádraig Brady
Subject: [PATCH] copy: fix SELinux context preservation for existing directories
Date: Sun, 5 Jan 2014 15:00:55 +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                     |    7 +++++++
 THANKS.in                |    1 +
 src/copy.c               |   13 ++++++++++++-
 tests/cp/cp-a-selinux.sh |   15 +++++++++++++++
 4 files changed, 35 insertions(+), 1 deletions(-)

diff --git a/NEWS b/NEWS
index 66884db..0d81f45 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,13 @@ GNU coreutils NEWS                                    -*- 
outline -*-
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** Bug fixes
+
+  cp -a again sets the correct SELinux context for existing directories in
+  the destination.  Previously it 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]
 
diff --git a/THANKS.in b/THANKS.in
index 6588376..5b3e96e 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -441,6 +441,7 @@ Michael Veksler                     address@hidden
 Michail Litvak                      address@hidden
 Michal Politowski                   address@hidden
 Michal Svec                         address@hidden
+Michal Trunecka                     address@hidden
 Michel Robitaille                   address@hidden
 Michiel Bacchiani                   address@hidden
 Mike Castle                         address@hidden
diff --git a/src/copy.c b/src/copy.c
index 557d37b..3e4cbff 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -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,
diff --git a/tests/cp/cp-a-selinux.sh b/tests/cp/cp-a-selinux.sh
index 79b1c0a..02e9b63 100755
--- a/tests/cp/cp-a-selinux.sh
+++ b/tests/cp/cp-a-selinux.sh
@@ -41,6 +41,21 @@ 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
+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_
+# Set the permissions of the source to show they're reset too
+chmod o+rw restore/existing_dir
+# 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
-- 
1.7.7.6




reply via email to

[Prev in Thread] Current Thread [Next in Thread]