1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-22 17:35:35 +03:00

Merge pull request #30023 from mrc0mmand/selinux

test: make TEST-06-SELINUX work with the refpolicy and beef it up a bit
This commit is contained in:
Luca Boccassi 2023-11-14 19:04:35 +00:00 committed by GitHub
commit e437b28054
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 66 additions and 123 deletions

View File

@ -1,2 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
/usr/lib/systemd/tests/testdata/testsuite-06\.units(/.*)? system_u:object_r:systemd_unit_file_t:s0

View File

@ -1,9 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
template(`systemd_test_base_template', `
gen_require(`
attribute systemd_test_domain_type;
')
type $1_t, systemd_test_domain_type;
domain_type($1_t)
')

View File

@ -1,51 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
policy_module(systemd_test, 0.0.1)
# declarations
attribute systemd_test_domain_type;
systemd_test_base_template(systemd_test)
systemd_test_base_template(systemd_test_status)
systemd_test_base_template(systemd_test_start)
systemd_test_base_template(systemd_test_stop)
systemd_test_base_template(systemd_test_reload)
# systemd_test_domain_type
require {
role system_r;
role unconfined_r;
type bin_t;
type initrc_t;
type systemd_systemctl_exec_t;
type unconfined_service_t;
}
role system_r types systemd_test_domain_type;
role unconfined_r types systemd_test_domain_type;
allow systemd_test_domain_type bin_t: file entrypoint;
allow systemd_test_domain_type systemd_systemctl_exec_t: file entrypoint;
allow initrc_t systemd_test_domain_type: process transition;
allow unconfined_service_t systemd_test_domain_type: process transition;
corecmd_exec_bin(systemd_test_domain_type)
init_signal_script(systemd_test_domain_type)
init_sigchld_script(systemd_test_domain_type)
systemd_exec_systemctl(systemd_test_domain_type)
userdom_use_user_ttys(systemd_test_domain_type)
userdom_use_user_ptys(systemd_test_domain_type)
optional_policy(`
dbus_system_bus_client(systemd_test_domain_type)
init_dbus_chat(systemd_test_domain_type)
')
# systemd_test_*_t
require {
type systemd_unit_file_t;
}
allow systemd_test_status_t systemd_unit_file_t: service { status };
allow systemd_test_start_t systemd_unit_file_t: service { start };
allow systemd_test_stop_t systemd_unit_file_t: service { stop };
allow systemd_test_reload_t systemd_unit_file_t: service { reload };

View File

@ -6,57 +6,38 @@ TEST_DESCRIPTION="SELinux tests"
IMAGE_NAME="selinux"
TEST_NO_NSPAWN=1
# Requirements:
# A selinux policy is installed. Preferably selinux-policy-targeted, but it could work with others
# selinux-policy-devel
if [[ -e /etc/selinux/config ]]; then
SEPOLICY="$(awk -F= '/^SELINUXTYPE=/ {print $2; exit}' /etc/selinux/config)"
# Check if
# - selinux-policy-devel is installed and
# - some selinux policy is installed. To keep this generic just check for the
# existence of a directory below /etc/selinux/, indicating a SELinux policy is
# installed
# otherwise bail out early instead of failing
test -f /usr/share/selinux/devel/include/system/systemd.if && find /etc/selinux -mindepth 1 -maxdepth 1 -not -empty -type d | grep -q . || exit 0
# C8S doesn't set SELINUXTYPE in /etc/selinux/config, so default to 'targeted'
if [[ -z "$SEPOLICY" ]]; then
echo "Failed to parse SELinux policy from /etc/selinux/config, falling back to 'targeted'"
SEPOLICY="targeted"
fi
if [[ ! -d "/etc/selinux/$SEPOLICY" ]]; then
echo "Missing policy directory /etc/selinux/$SEPOLICY, skipping the test"
exit 0
fi
echo "Using SELinux policy '$SEPOLICY'"
else
echo "/etc/selinux/config is missing, skipping the test"
exit 0
fi
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
SETUP_SELINUX=yes
KERNEL_APPEND="${KERNEL_APPEND:=} selinux=1 security=selinux"
KERNEL_APPEND="${KERNEL_APPEND:-} selinux=1 enforcing=0 lsm=selinux"
test_append_files() {
local workspace="${1:?}"
local policy_headers_dir=/usr/share/selinux/devel
local modules_dir=/var/lib/selinux
setup_selinux
# Make sure we never expand this to "/..."
rm -rf "${workspace:?}/$modules_dir"
if ! cp -ar "$modules_dir" "$workspace/$modules_dir"; then
dfatal "Failed to copy $modules_dir"
exit 1
fi
rm -rf "${workspace:?}/$policy_headers_dir"
inst_dir /usr/share/selinux
if ! cp -ar "$policy_headers_dir" "$workspace/$policy_headers_dir"; then
dfatal "Failed to copy $policy_headers_dir"
exit 1
fi
mkdir "$workspace/systemd-test-module"
cp -v systemd_test.* "$workspace/systemd-test-module/"
image_install checkmodule load_policy m4 make sefcontext_compile semodule semodule_package runcon
image_install -o sesearch
image_install -o /usr/libexec/selinux/hll/pp # Fedora/RHEL/...
image_install -o /usr/lib/selinux/hll/pp # Debian/Ubuntu/...
if ! chroot "$workspace" make -C /systemd-test-module -f /usr/share/selinux/devel/Makefile clean load systemd_test.pp QUIET=n; then
dfatal "Failed to build the systemd test module"
exit 1
fi
# Config file has (unfortunately) always precedence, so let's switch it there as well
sed -i '/^SELINUX=disabled$/s/disabled/permissive/' "$workspace/etc/selinux/config"
}
do_test "$@"

View File

@ -924,16 +924,13 @@ setup_selinux() {
return 0
fi
local conf_dir=/etc/selinux
local fixfiles_tools=(awk bash cat chcon expr egrep find grep head secon setfiles rm sort uname uniq)
# Make sure the following statement can't expand to "/" to prevent
# a potential where-are-my-backups situation
rm -rf "${initdir:?}/$conf_dir"
if ! cp -ar "$conf_dir" "$initdir/$conf_dir"; then
dfatal "Failed to copy $conf_dir"
exit 1
fi
for dir in /etc/selinux /usr/share/selinux; do
rm -rf "${initdir:?}/$dir"
if ! cp -ar "$dir" "$initdir/$dir"; then
dfatal "Failed to copy $dir"
exit 1
fi
done
# We use a custom autorelabel service instead of the SELinux provided set
# of units & a generator, since the generator overrides the default target
@ -944,13 +941,13 @@ setup_selinux() {
# and does the relabeling unconditionally which always ends with a reboot, so
# we end up in a reboot loop (and it also spews quite a lot of errors as it
# wants /etc/fstab and dracut-initramfs-restore).
touch "$initdir/.autorelabel"
mkdir -p "$initdir/usr/lib/systemd/tests/testdata/units/basic.target.wants"
ln -sf ../autorelabel.service "$initdir/usr/lib/systemd/tests/testdata/units/basic.target.wants/"
image_install "${fixfiles_tools[@]}"
image_install fixfiles sestatus
# Tools requires by fixfiles
image_install awk bash cat chcon expr egrep find grep head secon setfiles rm sort uname uniq
image_install fixfiles getenforce load_policy selinuxenabled sestatus
}
install_valgrind() {

View File

@ -3,14 +3,41 @@
set -eux
set -o pipefail
echo 1 >/sys/fs/selinux/enforce || {
echo "Can't make selinux enforcing, skipping test"
touch /testok
exit
}
# Note: ATTOW the following checks should work with both Fedora and upstream reference policy
# (with or without MCS/MLS)
runcon -t systemd_test_start_t systemctl start hola
runcon -t systemd_test_reload_t systemctl reload hola
runcon -t systemd_test_stop_t systemctl stop hola
sestatus
# We should end up in permissive mode
[[ "$(getenforce)" == "Permissive" ]]
# Check PID 1's context
PID1_CONTEXT="$(ps -h -o label 1)"
[[ "$PID1_CONTEXT" =~ ^system_u:system_r:init_t(:s0)?$ ]]
# The same label should be attached to all PID 1's journal messages
journalctl -q -b -p info -n 5 --grep . _SELINUX_CONTEXT="$PID1_CONTEXT"
# Check context on a couple of arbitrarily-selected files/directories
[[ "$(stat --printf %C /run/systemd/journal/)" =~ ^system_u:object_r:(syslogd_runtime_t|syslogd_var_run_t)(:s0)?$ ]]
[[ "$(stat --printf %C /run/systemd/notify)" =~ ^system_u:object_r:(init_runtime_t|init_var_run_t)(:s0)?$ ]]
[[ "$(stat --printf %C /run/systemd/sessions/)" =~ ^system_u:object_r:(systemd_sessions_runtime_t|systemd_logind_sessions_t)(:s0)?$ ]]
# Check if our SELinux-related functionality works
#
# Since the SELinux policies vary wildly, use a context from some existing file
# as our test context
CONTEXT="$(stat -c %C /proc/sys/kernel/core_pattern)"
[[ "$(systemd-run --wait --pipe -p SELinuxContext="$CONTEXT" cat /proc/self/attr/current | tr -d '\0')" == "$CONTEXT" ]]
(! systemd-run --wait --pipe -p SELinuxContext="foo:bar:baz" cat /proc/self/attr/current)
(! systemd-run --wait --pipe -p ConditionSecurity='selinux' false)
systemd-run --wait --pipe -p ConditionSecurity='!selinux' false
NSPAWN_ARGS=(systemd-nspawn -q --volatile=yes --directory=/ --bind-ro=/etc --inaccessible=/etc/machine-id)
[[ "$("${NSPAWN_ARGS[@]}" cat /proc/self/attr/current | tr -d '\0')" != "$CONTEXT" ]]
[[ "$("${NSPAWN_ARGS[@]}" --selinux-context="$CONTEXT" cat /proc/self/attr/current | tr -d '\0')" == "$CONTEXT" ]]
[[ "$("${NSPAWN_ARGS[@]}" stat --printf %C /run)" != "$CONTEXT" ]]
[[ "$("${NSPAWN_ARGS[@]}" --selinux-apifs-context="$CONTEXT" stat --printf %C /run)" == "$CONTEXT" ]]
[[ "$("${NSPAWN_ARGS[@]}" --selinux-apifs-context="$CONTEXT" --tmpfs=/tmp stat --printf %C /tmp)" == "$CONTEXT" ]]
touch /testok