Bug 1045122
| Summary: | cp -a messes up destination selinux contexts for existing directories | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 7 | Reporter: | Michal Trunecka <mtruneck> | ||||||
| Component: | coreutils | Assignee: | Ondrej Vasik <ovasik> | ||||||
| Status: | CLOSED CURRENTRELEASE | QA Contact: | Tomas Dolezal <todoleza> | ||||||
| Severity: | urgent | Docs Contact: | |||||||
| Priority: | urgent | ||||||||
| Version: | 7.0 | CC: | dwalsh, ebenes, jscotka, ksrot, mfranc, mmalik, mtruneck, ovasik, pbrady, sgraf, todoleza | ||||||
| Target Milestone: | rc | Keywords: | Regression, TestBlocker | ||||||
| Target Release: | 7.0 | ||||||||
| Hardware: | All | ||||||||
| OS: | Linux | ||||||||
| Whiteboard: | |||||||||
| Fixed In Version: | coreutils-8.22-5.el7 | Doc Type: | Bug Fix | ||||||
| Doc Text: | Story Points: | --- | |||||||
| Clone Of: | Environment: | ||||||||
| Last Closed: | 2014-06-13 11:16:49 UTC | Type: | Bug | ||||||
| Regression: | --- | Mount Type: | --- | ||||||
| Documentation: | --- | CRM: | |||||||
| Verified Versions: | Category: | --- | |||||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||||
| Embargoed: | |||||||||
| Bug Depends On: | |||||||||
| Bug Blocks: | 798670 | ||||||||
| Attachments: |
|
||||||||
Thanks Michal for looking at this - adding Dan Walsh to CC - as he is the author of most of the upstream changes...
There is one divergency in SELinux copy mechanism in downstream SELinux coreutils-8.22 patch - so pasting it here to be sure. I'll try to analyze it while on Christmas break.
diff -urNp coreutils-8.21-orig/src/copy.c coreutils-8.21/src/copy.c
--- coreutils-8.21-orig/src/copy.c 2013-02-07 10:37:05.000000000 +0100
+++ coreutils-8.21/src/copy.c 2013-02-15 14:31:58.941467872 +0100
@@ -2315,6 +2315,8 @@ copy_internal (char const *src_name, cha
{
/* Here, we are crossing a file system boundary and cp's -x option
is in effect: so don't copy the contents of this directory. */
+ if (x->preserve_security_context)
+ restore_default_fscreatecon_or_die ();
}
else
{
Are you saying we added or removed + if (x->preserve_security_context) + restore_default_fscreatecon_or_die (); No, this is part of our downstream patch which is in Fedora/RHEL for ages. As most of the things are already accepted upstream, this one is the only remaining chunk in copy.c - probably it is not connected to the issue. Is this specific for ppc64? It seems to work properly on my machine (ok, compiled coreutils-8.22 on F20, I haven't tried the rhel7 machine yet). Can you please provide strace of the failure? TIA. Then the problem looks like it is calling setfscreatecon(krb5kdc_conf_t) before to create the target file but not for the intermediate directories.
/var/tmp/beakerlib-meTuGkC/backup-krb5/var/kerberos/krb5kdc/kdc.conf
root_t---^ ^ ^ ^ ^
var_t-----^ ^ ^ ^
var_t------------^ ^ ^
krb5kdc_conf_t--^--------^
IE is should be calling
setfsreatecon(root_t); mkdir backup-krb5
setfsreatecon(var_t); mkdir var
setfsreatecon(var_t); mkdir kerberos
setfsreatecon(krb5kdc_conf_t); mkdir krb5kdc
setfsreatecon(krb5kdc_conf_t); create kdc.conf
Created attachment 844440 [details]
Strace output of the reproducing cp command
Yes, it is reproducible on x86_64 too, attached strace of the command.
# rpm -q coreutils
coreutils-8.22-1.el7.x86_64
Hmmms, from strace it clearly calls setxattr "unconfined_u:object_r:krb5kdc_conf_t:s0" on /var ... strange - it really works just fine on my F20 x86_64 machine with the same coreutils build. I'm going to compare the straces. One suspicious thing - warnings about missing /var/run/setrans/.setrans-unix socket file - is mcstrans service running? No, mcstrans was not even installed. But the bug is still reproducible after installing and running mcstrans daemon. Ok, now I see - my reproducer on F20 was "slightly modified" - copying the output to non-existing directory - that worked (-f was not in action). I'm able to reproduce it now - it seems to correctly copy the context if the file/directory doesn't exist before the command, it screws up the context if the directory existed before the command. Further investigating. I believe this is caused by this chunk from the http://git.savannah.gnu.org/cgit/coreutils.git/commit/src/copy.c?id=7958a4a4fe234f9787daf178a60bc83449605dac ... as -a turns on the x->preserve_security_context ... @@ -2521,6 +2596,19 @@ copy_internal (char const *src_name, char const *dst_name, goto un_backup; } + /* 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 + && (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; + } + } + if (command_line_arg && x->dest_info) { /* Now that the destination file is very likely to exist, Adding upstream maintainer to CC to let him notified about this regression. I believe "|| x->require_preserve_context" should be used there. Anyway - this chunk is probably wrong in general, as it sets the context of all recursive subdirs to the context of destination file. Ugh. What created the backup BTW? I'm not sure that any version of `cp -a` copies intermediate directory contexts. Anyway looking at this now... The backup was not created by single cp command, but by Beaker rlFileBackup function, which creates the path using mkdir and assigns the contexts using chcon. Created attachment 844620 [details]
proposed fix
I need to add a test for this before pushing upstream, but it should fix this issue.
I also noticed the related issue that the context is not set for new
dirs when using --parents
Thanks Pádraig... I can confirm that the scenario in the Bug Description works as expected now with coreutils-8.22-5.el7.x86_64. The proposed upstream commit also includes a test http://lists.gnu.org/archive/html/coreutils/2014-01/msg00012.html This request was resolved in Red Hat Enterprise Linux 7.0. Contact your manager or support representative in case you have further questions about the request. |
Description of problem: This is a regression in coreutils version 8.22-1 In our tests, we have backups like this, with given (correctly backed up) contexts: /var/tmp/beakerlib-meTuGkC/backup-krb5/var/kerberos/krb5kdc/kdc.conf root_t---^ ^ ^ ^ ^ var_t-----^ ^ ^ ^ var_t------------^ ^ ^ krb5kdc_conf_t--^--------^ But after restoring the backup, which is done by cp -fa /var/tmp/beakerlib-meTuGkC/backup-krb5/var / it assigns the krb5kdc_conf_t context to the whole destination path! It means that /var has this context and the whole system is broken by this. Version-Release number of selected component (if applicable): coreutils-8.22-1.el7.ppc64 How reproducible: always Expected results: cp -fa should preserve the original contexts