Bug 1559808

Summary: SELinux resets local customizations upon relabelling when /etc/selinux/fixfiles_exclude_dirs contains a path
Product: Red Hat Enterprise Linux 7 Reporter: Renaud Métrich <rmetrich>
Component: policycoreutilsAssignee: Vit Mojzis <vmojzis>
Status: CLOSED ERRATA QA Contact: Jan Zarsky <jzarsky>
Severity: medium Docs Contact:
Priority: medium    
Version: 7.4CC: dapospis, dwalsh, jzarsky, kyoneyam, lvrabec, mgrepl, mmalik, plautrba, ssekidde, vmojzis, zpytela
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2018-10-30 09:46:43 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:

Description Renaud Métrich 2018-03-23 10:20:52 UTC
Description of problem:

When having local customizations and /etc/selinux/fixfiles_exclude_dirs containing a path, relabelling the filesystems using "fixfiles -F restore" or "touch /.autorelabel && reboot" leads to the customized contexts to not be applied.

After relabelling, a restorecon needs to be issued to restore the customizations.


Version-Release number of selected component (if applicable):

policycoreutils-2.5-17.1.el7.x86_64


How reproducible:

Always


Steps to Reproduce:
1. Create a dummy file and customized context

  # touch /usr/local/bin/dummy
  # semanage fcontext -a -t shell_exec_t /usr/local/bin/dummy
  # restorecon -F /usr/local/bin/dummy
  # ls -Z /usr/local/bin/dummy
  -rw-r--r--. root root system_u:object_r:shell_exec_t:s0 /usr/local/bin/dummy

2. Add a existing directory to /etc/selinux/fixfiles_exclude_dirs

  # mkdir /mydir
  # echo "/mydir" > /etc/selinux/fixfiles_exclude_dirs

3. Run "fixfiles -F restore" (this is what is done when touching /.autorelabel and rebooting)

  # fixfiles -F restore

4. Verify context

  # ls -Z /usr/local/bin/dummy


Actual results: (bin_t)

  -rw-r--r--. root root system_u:object_r:bin_t:s0       /usr/local/bin/dummy


Expected results: (shell_exec_t)

  -rw-r--r--. root root system_u:object_r:shell_exec_t:s0 /usr/local/bin/dummy


Additional info:

Running fixfiles with tracing (set -x; set -o functrace), we can see that the contexts file passed to "setfiles" is different (it is some "temporary" file used when exclucing a directory, and not the standard file):

/tmp/fixfiles.ko:+ SETFILES=/sbin/setfiles
/tmp/fixfiles.ko:+ /sbin/setfiles -e /mydir -q -F /etc/selinux/targeted/contexts/files/file_contexts.RTPjVxc8cB / /boot /dev /dev/hugepages /dev/mqueue /dev/pts /dev/shm /run 

/tmp/fixfiles.ok:+ SETFILES=/sbin/setfiles
/tmp/fixfiles.ok:+ /sbin/setfiles -q -F /etc/selinux/targeted/contexts/files/file_contexts / /boot /dev /dev/hugepages /dev/mqueue /dev/pts /dev/shm /run /run/user/0 /sys /usr

Comment 2 Renaud Métrich 2018-03-23 11:52:47 UTC
The following code snippet is responsible for the issue:

# cat /usr/sbin/fixfiles
...
141 FC_SUB_DIST=${FC}.subs_dist
142 FC_SUB=${FC}.subs
143 FC_HOMEDIRS=${FC}.homedirs
...
236 exclude_dirs="`exclude_dirs_from_relabelling $OPTION`"
237 if [ -n "${exclude_dirs}" ]
238 then
239 >-------TEMPFCFILE=`mktemp ${FC}.XXXXXXXXXX`
240 >-------test -z "$TEMPFCFILE" && exit
241 >-------/bin/cp -p ${FC} ${TEMPFCFILE} &>/dev/null || exit
242 >-------tmpdirs=${tempdirs//-e/}
243 >-------for p in ${tmpdirs}
244 >-------do
245 >------->-------p="${p%/}"
246 >------->-------p1="${p}(/.*)? -- <<none>>"
247 >------->-------echo "${p1}" >> $TEMPFCFILE
248 >------->-------logit "skipping the directory ${p}"
249 >-------done
250 FC=$TEMPFCFILE
251 /bin/cp -p ${FC_SUB_DIST} ${TEMPFCFILE}.subs_dist &>/dev/null || exit
252 /bin/cp -p ${FC_SUB} ${TEMPFCFILE}.subs &>/dev/null || exit
253 /bin/cp -p ${FC_HOMEDIRS} ${TEMPFCFILE}.homedirs &>/dev/null || exit
254 
255 fi

--> When excluding directories, the ${FC} file (/etc/selinux/targeted/contexts/files/file_contexts) is copied to a temporary location. Clearly the ${FC_LOCAL} (not defined, see below) is missing on line 144 and the corresponding copy on line 254.

FC_LOCAL=${FC}.local
/bin/cp -p ${FC_LOCAL} ${TEMPFCFILE}.local &>/dev/null || exit

Please fix the missing indentation for lines 251-253 as part of the fix.

Comment 6 Vit Mojzis 2018-07-09 16:10:24 UTC
*** Bug 1599114 has been marked as a duplicate of this bug. ***

Comment 10 errata-xmlrpc 2018-10-30 09:46:43 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2018:3098