#!/bin/bash
# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# runtest.sh of /CoreOS/selinux-policy/Sanity/serge-testsuite
# Description: functional test suite for the LSM-based SELinux security module
# Author: Milos Malik <mmalik@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2014 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Include Beaker environment
. /usr/bin/rhts-environment.sh || exit 1
. /usr/share/beakerlib/beakerlib.sh || exit 1
PACKAGE="selinux-policy"
# Default commit to checkout from the repo.
# This should be updated as needed after verifying that the new version
# doesn't break testing and after applying all necessary tweaks in the TC.
# Run with GIT_BRANCH=master to run the latest upstream version.
DEFAULT_COMMIT="b03e3453786cb20a16546d7743d31e5f26bfda3d"
# Default pull requests to merge before running the test.
# If non-empty, then after checking out GIT_BRANCH the listed upstream pull
# requests (by number) are merged, creating a new temporary local branch.
DEFAULT_PULLS=""
# Default SELinux Patchwork series to apply before running the test.
DEFAULT_PATCHES="208221 207155"
# Optional test parameter - location of testuite git.
GIT_URL=${GIT_URL:-"git://github.com/SELinuxProject/selinux-testsuite"}
# Optional test parameter - branch containing tests.
if [ -z "$GIT_BRANCH" ]; then
GIT_BRANCH="$DEFAULT_COMMIT"
# Use default cherries only if branch is default and they are not overriden
GIT_PULLS="${GIT_PULLS:-"$DEFAULT_PULLS"}"
GIT_PATCHES="${GIT_PATCHES:-"$DEFAULT_PATCHES"}"
fi
# Check if pipefail is enabled to restore original setting.
# See: https://unix.stackexchange.com/a/73180
if false | true; then
PIPEFAIL_ENABLE="set -o pipefail"
PIPEFAIL_DISABLE="set +o pipefail"
else
PIPEFAIL_ENABLE=""
PIPEFAIL_DISABLE=""
fi
if rlIsRHEL 5 ; then
# On RHEL-5 sort -V doesn't work, so just pretend we have the oldest kernel
function kver_ge() { false; }
function kver_lt() { true; }
function kver_le() { true; }
function kver_gt() { false; }
else
function version_le() {
{ echo "$1"; echo "$2"; } | sort -V | tail -n 1 | grep -qx "$2"
}
function kver_ge() { version_le "$1" "$(uname -r)"; }
function kver_lt() { ! kver_ge "$1"; }
function kver_le() { version_le "$(uname -r)" "$1"; }
function kver_gt() { ! kver_le "$1"; }
fi
function installDepsYum() {
local yum="$1"; shift
if "$yum" --help | grep -q -- --skip-broken; then
"$yum" install -y --skip-broken $*
else
for req in $*; do
if ! rpm -q --quiet --whatprovides "$req"; then
"$yum" install -y "$req" || true
fi
done
fi
}
function installDeps() {
if type yum >/dev/null; then
installDepsYum yum "$@"
elif type dnf >/dev/null; then
installDepsYum dnf "$@"
fi
}
function boolGet() {
getsebool "$1" | cut -d ' ' -f 3
}
function boolSet() {
getsebool -a | cut -d ' ' -f 1 | grep "^$1\$" || return 0
setsebool "$1" "$2" || return 1
[ "$(boolGet "$1")" == "$2" ]
}
rlJournalStart
rlPhaseStartSetup "Install"
# We need to install the kernel-* packages by ourselves, since we need
# the same versions as the running kernel. And since we already need a
# reliable package install function, let's just install all the
# dependencies here. Thus we don't need to maintain duplicate lists of
# package requirements in many places (RH repo, Fedora kernel dist-git,
# CKI).
PKG_SUFFIX=""
KERNEL_VERSION="$(uname -r)"
PKG_VERSION="${KERNEL_VERSION%+debug}"
if [ "$PKG_VERSION" != "$KERNEL_VERSION" ]; then
rlLog "Detected debug kernel running."
PKG_SUFFIX="-debug"
fi
REQUIRES="
kernel$PKG_SUFFIX-modules-extra-$PKG_VERSION
kernel-rt$PKG_SUFFIX-modules-extra-$PKG_VERSION
kernel$PKG_SUFFIX-devel-$PKG_VERSION
kernel-rt$PKG_SUFFIX-devel-$PKG_VERSION
/usr/bin/unbuffer
attr
audit
checkpolicy
curl
elfutils-libelf-devel
expect
gcc
git
grep
ipsec-tools
iptables
keyutils-libs-devel
libbpf-devel
libibverbs-devel
libselinux
libselinux-devel
libselinux-utils
libsemanage
libsepol-devel
lksctp-tools-devel
mktemp
nc
netlabel_tools
net-tools
nmap-ncat
perl-Test
perl-Test-Harness
perl-Test-Simple
platform-python
policycoreutils
policycoreutils-devel
policycoreutils-python
python3
python2-lxml
python3-lxml
rdma-core-devel
selinux-policy
selinux-policy-devel
setools-console
which
"
rlRun "installDeps \$REQUIRES" 0 "Install requires"
rlPhaseEnd
rlPhaseStartSetup
rlAssertRpm ${PACKAGE}
rlAssertRpm audit
rlAssertRpm kernel
rlFileBackup /etc/selinux/semanage.conf
# running the testsuite in /tmp causes permission denied messages
# rlRun "TmpDir=\$(mktemp -d)" 0 "Creating tmp directory"
# rlRun "pushd $TmpDir"
if ! rlIsRHEL 5 ; then
# version_le() sanity check:
rlRun "version_le 4.10 4.10"
rlRun "version_le 4.10 4.10.0"
rlRun "version_le 4.10 4.10.1"
rlRun "! version_le 4.10 4.9"
rlRun "! version_le 4.10.0 4.10"
fi
# test turns this boolean off
rlRun "BACKUP_allow_domain_fd_use=\$(boolGet allow_domain_fd_use)"
rlRun "BACKUP_domain_can_mmap_files=\$(boolGet domain_can_mmap_files)"
# test expects that domains cannot map files by default
rlRun "boolSet domain_can_mmap_files off"
rlRun "setenforce 1"
rlRun "sestatus"
if grep 'expand-check' /etc/selinux/semanage.conf; then
rlRun "sed -i 's/^expand-check[ ]*=.*$/expand-check = 0/' /etc/selinux/semanage.conf"
else
rlRun "echo 'expand-check = 0' >>/etc/selinux/semanage.conf"
fi
if [ ! -d selinux-testsuite ] && rlRun "git clone $GIT_URL" 0; then
rlRun "pushd selinux-testsuite"
rlRun "git checkout $GIT_BRANCH" 0
for _ in $GIT_PULLS $GIT_PATCHES; do
rlRun "git config --global user.email nobody@redhat.com"
rlRun "git config --global user.name 'Nemo Nobody'"
rlRun "git checkout -b testing-cherry-picks" 0
break
done
for pull in $GIT_PULLS; do
ref="refs/pull/$pull/head"
if ! rlRun "git fetch origin $ref:$ref" 0; then
rlRun "git checkout $GIT_BRANCH" 0
rlWarn "PR merge failed, falling back to GIT_BRANCH"
break
fi
if ! rlRun "git merge --no-edit $ref" 0; then
rlRun "git merge --abort" 0
rlRun "git checkout $GIT_BRANCH" 0
rlWarn "PR merge failed, falling back to GIT_BRANCH"
break
fi
done
for pwseries in $GIT_PATCHES; do
url="https://patchwork.kernel.org/series/$pwseries/mbox/"
if ! rlRun "curl $url | git am -"; then
rlRun "git checkout $GIT_BRANCH" 0
rlWarn "Applying patch failed, falling back to GIT_BRANCH"
break
fi
done
rlRun "popd"
fi
if [ -d selinux-testsuite ]; then
rlRun "pushd selinux-testsuite"
# backup code before making tweaks
rlFileBackup "."
if [ "$VERBOSE" = "1" ]; then
rlRun "sed -i 's/\(use Test::Harness;\)/\1 \$Test::Harness::verbose = TRUE;/' tests/runtests.pl" 0 \
"Enable verbose output"
fi
exclude_tests=""
for file in ./tests/nnp*/execnnp.c; do
rlRun "sed -i 's/3.18/3.9/' $file" 0 \
"Fix up kernel version in nnp test"
done
if rlIsRHEL ; then
rlRun "sed -i 's/4.20.17/4.18/' tests/Makefile" 0 \
"Fix up kernel version for sctp test"
rlRun "sed -i 's/5.2/4.18.0-80.19/' tests/Makefile" 0 \
"Fix up kernel version for cgroupfs_label test"
# CONFIG_KEYS_DH_COMPUTE not enabled on RHEL-8 :(
exclude_tests+=" keys"
fi
if rlIsRHEL 5 ; then
rlRun "sed -i '/unconfined_devpts_t/d' policy/test_policy.if" 0
rlRun "sed -i 's/read_file_perms/r_file_perms/' policy/*.te" 0
rlRun "sed -i 's/mmap_file_perms/rx_file_perms/' policy/*.te" 0
rlRun "sed -i 's/list_dir_perms/r_dir_perms/' policy/*.te" 0
rlRun "sed -i 's/ open / /' policy/*.te" 0
rlRun "sed -i 's/^sysadm_bin_spec_domtrans_to/userdom_sysadm_bin_spec_domtrans_to/' policy/*.te" 0
rlRun "sed -i 's/^corecmd_exec_bin(\(.*\))$/corecmd_exec_bin(\1)\ncorecmd_exec_sbin(\1)/' policy/*.te" 0
rlRun "sed -i 's/^corecmd_bin_entry_type(\(.*\))$/corecmd_bin_entry_type(\1)\ncorecmd_sbin_entry_type(\1)/' policy/*.te" 0
rlRun "sed -i 's/^userdom_search_user_home_dirs(\(.*\))$/userdom_search_user_home_dirs(user, \1)/' policy/*.te" 0
fi
if ! [ -x /usr/bin/python3 ]; then
# to avoid error messages like runcon: ‘overlay/access’: No such file or directory
rlRun "rpm -qa | grep python | sort"
rlRun "sed -i 's/python3\$/python2/' tests/overlay/access" 0 \
"Fix up Python shebang in overlay test"
fi
if kver_lt "3.10.0-349"; then
# c4684bbdac07 [security] selinux: Permit bounded transitions under NO_NEW_PRIVS or NOSUID
# da74590f6501 [security] selinux: reject setexeccon() on MNT_NOSUID applications with -EACCES
exclude_tests+=" nnp_nosuid"
fi
if kver_lt "3.10.0-693"; then
# I don't know when exactly this test starts passing, so I'm just
# disabling it for anything below the RHEL-7.4 kernel...
exclude_tests+=" inet_socket"
fi
if kver_lt "3.10.0-875"; then
rlLog "No xperms support => disable xperms testing"
rlRun "sed -i '/TARGETS += test_ioctl_xperms\.te/d' policy/Makefile"
rlRun "sed -i 's/\$kernver >= 30/\$kernver >= 999999/' tests/ioctl/test"
fi
# workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1613056
# (if running kernel version sorts inside the known-bug window, then
# we need to apply the workaround)
if kver_ge "3.10.0-875" && kver_lt "3.10.0-972"; then
rlLog "Applying workaround for BZ 1613056..."
rlRun "cat >>policy/test_ipc.te <<<'allow_map(ipcdomain, tmpfs_t, file)'"
rlRun "cat >>policy/test_mmap.te <<<'allow_map(test_execmem_t, tmpfs_t, file)'"
rlRun "cat >>policy/test_mmap.te <<<'allow_map(test_no_execmem_t, tmpfs_t, file)'"
fi
if rlIsRHEL || [ "$(rlGetPrimaryArch)" != x86_64 ]; then
rlRun "sed -i '/SUBDIRS += bpf/d;/export CFLAGS += -DHAVE_BPF/d' tests/Makefile" 0 \
"Disable BPF tests on RHEL and non-x86_64 Fedora"
fi
if [ -n "$exclude_tests" ] ; then
rlRun "sed -i '/^[^[:space:]]*:\(\| .*\)\$/i SUBDIRS:=\$(filter-out $exclude_tests, \$(SUBDIRS))' tests/Makefile" 0 \
"Exclude not applicable tests: $exclude_tests"
fi
if ! modprobe sctp 2>/dev/null; then
script1='s/runcon -t test_sctp_socket_t/true/g'
script2='s/runcon -t test_no_sctp_socket_t/false/g'
rlRun "sed -i -e '$script1' -e '$script2' ./tests/extended_socket_class/test" 0 \
"No SCTP support => fix up extended_socket_class test"
fi
# on aarch64 and s390x the kernel support for Bluetooth is turned
# off so we disable the Bluetooth socket tests there
case "$(rlGetPrimaryArch)" in
aarch64|s390x)
script1='s/runcon -t test_bluetooth_socket_t/true/g'
script2='s/runcon -t test_no_bluetooth_socket_t/false/g'
rlRun "sed -i -e '$script1' -e '$script2' ./tests/extended_socket_class/test" 0 \
"No Bluetooth support => fix up extended_socket_class test"
;;
esac
# Initialize report.
rlRun "echo 'Remote: $GIT_URL' >results.log" 0
rlRun "echo 'Branch: $GIT_BRANCH' >>results.log" 0
rlRun "echo 'Commit: $(git rev-parse $GIT_BRANCH)' >>results.log" 0
rlRun "echo 'GH PRs: ${GIT_PULLS:-"(none)"}' >>results.log" 0
rlRun "echo 'Series: ${GIT_PATCHES:-"(none)"}' >>results.log" 0
rlRun "echo 'Kernel: $(uname -r)' >>results.log" 0
rlRun "echo 'Policy: $(rpm -q selinux-policy)' >>results.log" 0
rlRun "echo ' $(rpm -q checkpolicy)' >>results.log" 0
rlRun "echo ' $(rpm -q libselinux)' >>results.log" 0
rlRun "echo ' $(rpm -q libsemanage)' >>results.log" 0
rlRun "echo ' $(rpm -q libsepol)' >>results.log" 0
rlRun "echo ' $(rpm -q policycoreutils)' >>results.log" 0
rlRun "echo '' >>results.log" 0
rlRun "popd"
fi
rlPhaseEnd
rlPhaseStartTest
if [ -d selinux-testsuite ]; then
rlRun "pushd selinux-testsuite"
rlRun "env -u ARCH make" 0
rlRun "cat results.log" 0
$PIPEFAIL_ENABLE
# DISTRO= needed for policy devel Makefile... (Beaker sets it to "redhat")
rlRun "env -u ARCH -u DISTRO LANG=C unbuffer make -s test 2>&1 | tee -a results.log" 0
$PIPEFAIL_DISABLE
rlRun "popd"
else
rlFail "GIT was unable to clone the testsuite repo"
fi
rlPhaseEnd
rlPhaseStartCleanup
# rlSEBooleanRestore
# rlSEBooleanRestore allow_domain_fd_use
# none of above-mentioned commands is able to correctly restore the value in the boolean
rlRun "boolSet domain_can_mmap_files $BACKUP_domain_can_mmap_files"
rlRun "boolSet allow_domain_fd_use $BACKUP_allow_domain_fd_use"
if [ -d selinux-testsuite ]; then
rlRun "pushd selinux-testsuite"
# Submit report to beaker.
rlFileSubmit "results.log" "selinux-testsuite.results.$(uname -r).txt"
rlRun "make clean" 0-2
rlRun "popd"
fi
rlRun "semodule -r test_policy" 0,1
rlRun "sleep 5" 0
rlRun "dmesg | grep -i \"rcu_sched detected stalls\"" 1
rlFileRestore
rlPhaseEnd
rlJournalPrintText
rlJournalEnd