From 5089e4e54117473e6d5ae37ac1ae629552e385ed Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Fri, 21 Jul 2017 10:49:26 +1000 Subject: [PATCH] Move setfiles to outside chroot with runcon As described in the comments inline, on a selinux enabled kernel (such as a centos build host) you need to have permissions to change the contexts to those the kernel doesn't understand -- such as when you're building a fedora image. For some reason, setfiles has an arbitrary limit of 10 errors before it stops. I believe we previously had 9 errors (this mean 9 mis-labeled files, which were just waiting to cause problems). Something changed with F26 setfiles and it started erroring immediately, which lead to investigation. Infra builds, on non-selinux Ubuntu kernel's, would not have hit this issue. This means we need to move this to run with a manual chroot into the image under restorecon. I'm really not sure why ironic-agent removes all the selinux tools from the image, it seems like an over-optimisation (it's been like that since Id6333ca5d99716ccad75ea1964896acf371fa72a). Keep them so we can run the relabel. Change-Id: I4f5b591817ffcd776cbee0a0f9ca9f48de72aa6b --- .../finalise.d/99-remove-extra-packages | 2 +- .../cleanup.d/99-selinux-fixfiles-restore | 74 +++++++++++++++++++ .../finalise.d/90-selinux-fixfiles-restore | 38 ---------- 3 files changed, 75 insertions(+), 39 deletions(-) create mode 100755 diskimage_builder/elements/rpm-distro/cleanup.d/99-selinux-fixfiles-restore delete mode 100755 diskimage_builder/elements/rpm-distro/finalise.d/90-selinux-fixfiles-restore diff --git a/diskimage_builder/elements/ironic-agent/finalise.d/99-remove-extra-packages b/diskimage_builder/elements/ironic-agent/finalise.d/99-remove-extra-packages index 4a092985e..c4d7600b2 100755 --- a/diskimage_builder/elements/ironic-agent/finalise.d/99-remove-extra-packages +++ b/diskimage_builder/elements/ironic-agent/finalise.d/99-remove-extra-packages @@ -19,7 +19,7 @@ if [ $DISTRO_NAME = 'fedora' ] ; then install-packages -e kernel-debug-devel gcc fedora-logos \ rsync pykickstart \ make genisoimage tcpdump \ - man-db policycoreutils kbd-misc \ + man-db kbd-misc \ plymouth cronie ${_remove_yum} ${YUM:-yum} clean all diff --git a/diskimage_builder/elements/rpm-distro/cleanup.d/99-selinux-fixfiles-restore b/diskimage_builder/elements/rpm-distro/cleanup.d/99-selinux-fixfiles-restore new file mode 100755 index 000000000..c4b1e1ebd --- /dev/null +++ b/diskimage_builder/elements/rpm-distro/cleanup.d/99-selinux-fixfiles-restore @@ -0,0 +1,74 @@ +#!/bin/bash + +if [ ${DIB_DEBUG_TRACE:-1} -gt 0 ]; then + set -x +fi +set -eu +set -o pipefail + +# parser isn't smart enough to figure out \ +# dib-lint: disable=safe_sudo + +# Here be dragons ... a previous dragon slayer helpfully pointed out in +# http://www.spinics.net/lists/selinux/msg17379.html +# +# Not all of the contexts defined by the offline system's +# file_contexts may be valid under the policy of the host on which +# you are running (e.g. if they run different distributions or even +# different releases of the same distribution), which will normally +# prevent setting those contexts (the kernel won't recognize them). +# If you have this issue, you'll need to run setfiles as root in a +# special domain, setfiles_mac_t, that is allowed to set contexts +# unknown to the host policy, and likely chrooted so that it doesn't +# ask the kernel whether the contexts are valid via +# /sys/fs/selinux/context. That is how livecd-creator supported +# creating images for other releases. + +# One issue you might see without fixing selinux file labels is sshd +# will run in the kernel_t domain instead of the sshd_t domain, making +# ssh connections fail with "Unable to get valid context for " +# error message. Other failures will occur too. + +# XXX: is it really valid to build rpm-distros without this? +if [[ ! -f ${TARGET_ROOT}/etc/selinux/targeted/contexts/files/file_contexts ]]; then + echo "No selinux policy found in chroot, skipping..." + exit 0 +fi + +if [[ ! -x ${TARGET_ROOT}/usr/sbin/setfiles ]]; then + echo "Can not find setfiles in chroot!" + exit 1 +fi + +# If we're on a selinux system, enable permissive mode for +# setfiles_mac_t so we can relabel within the chroot without concern +# for whatever policy is in the host kernel. We will run under +# "runcon" to specifically allow this +_runcon="" +if [[ -x /usr/sbin/semanage ]]; then + sudo semanage permissive -a setfiles_mac_t + _runcon="runcon -t setfiles_mac_t -- " +fi + +# setfiles in > Fedora 26 added this flag: +# do not read /proc/mounts to obtain a list of +# non-seclabel mounts to be excluded from relabeling +# checks. Setting this option is useful where there is +# a non-seclabel fs mounted with a seclabel fs +# this describes our situation of being on a loopback device on +# an ubuntu system, say. See also +# https://bugzilla.redhat.com/show_bug.cgi?id=1472709 +_dash_m="" +if [[ $DISTRO_NAME == "fedora" && $DIB_RELEASE -ge 26 ]]; then + _dash_m+="-m" +fi + +IFS='|' read -ra SPLIT_MOUNTS <<< "$DIB_MOUNTPOINTS" +for MOUNTPOINT in "${SPLIT_MOUNTS[@]}"; do + if [ "${MOUNTPOINT}" != "/tmp/in_target.d" ] && [ "${MOUNTPOINT}" != "/dev" ]; then + sudo ${_runcon} chroot ${TARGET_ROOT} \ + /usr/sbin/setfiles -F ${_dash_m} \ + /etc/selinux/targeted/contexts/files/file_contexts ${MOUNTPOINT} + fi +done + diff --git a/diskimage_builder/elements/rpm-distro/finalise.d/90-selinux-fixfiles-restore b/diskimage_builder/elements/rpm-distro/finalise.d/90-selinux-fixfiles-restore deleted file mode 100755 index ebe6ddfa9..000000000 --- a/diskimage_builder/elements/rpm-distro/finalise.d/90-selinux-fixfiles-restore +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -if [ ${DIB_DEBUG_TRACE:-1} -gt 0 ]; then - set -x -fi -set -eu -set -o pipefail - -SETFILES=$(type -p setfiles || true) -if [ -e /etc/selinux/targeted/contexts/files/file_contexts -a -x "${SETFILES}" ]; then - # get all mounpoints in the system - IFS='|' read -ra SPLIT_MOUNTS <<< "$DIB_MOUNTPOINTS" - for MOUNTPOINT in "${SPLIT_MOUNTS[@]}"; do - # Without fixing selinux file labels, sshd will run in the kernel_t domain - # instead of the sshd_t domain, making ssh connections fail with - # "Unable to get valid context for " error message - if [ "${MOUNTPOINT}" != "/tmp/in_target.d" ] && [ "${MOUNTPOINT}" != "/dev" ]; then - # setfiles in > Fedora 26 added this flag: - # do not read /proc/mounts to obtain a list of - # non-seclabel mounts to be excluded from relabeling - # checks. Setting this option is useful where there is - # a non-seclabel fs mounted with a seclabel fs - # this describes our situation of being on a loopback device on - # an ubuntu system, say. See also - # https://bugzilla.redhat.com/show_bug.cgi?id=1472709 - _dash_m="" - if [[ $DISTRO_NAME == "fedora" && $DIB_RELEASE -ge 26 ]]; then - _dash_m+="-m" - fi - $SETFILES ${_dash_m} /etc/selinux/targeted/contexts/files/file_contexts ${MOUNTPOINT} - fi - done -else - echo "Skipping SELinux relabel, since setfiles is not available." - echo "Touching /.autorelabel to schedule a relabel when the image boots." - touch /.autorelabel -fi -