1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0-or-later
3# Copyright (c) 2018 Petr Vorel <pvorel@suse.cz>
4
5if [ -z "$TST_LIB_LOADED" ]; then
6	echo "please load tst_test.sh first" >&2
7	exit 1
8fi
9
10[ -n "$TST_SECURITY_LOADED" ] && return 0
11TST_SECURITY_LOADED=1
12
13_tst_check_security_modules()
14{
15	local cmd
16	local profiles
17
18	if tst_apparmor_enabled; then
19		tst_res TINFO "AppArmor enabled, this may affect test results"
20		[ "$TST_DISABLE_APPARMOR" = 1 ] || \
21			tst_res TINFO "it can be disabled with TST_DISABLE_APPARMOR=1 (requires super/root)"
22		profiles=
23		for cmd in $TST_NEEDS_CMDS; do
24			tst_apparmor_used_profile $cmd && profiles="$cmd $profiles"
25		done
26		[ -z "$profiles" ] && profiles="none"
27		tst_res TINFO "loaded AppArmor profiles: $profiles"
28	fi
29
30	if tst_selinux_enabled; then
31		tst_res TINFO "SELinux enabled in enforcing mode, this may affect test results"
32
33		[ "$TST_DISABLE_SELINUX" = 1 ] || \
34			tst_res TINFO "it can be disabled with TST_DISABLE_SELINUX=1 (requires super/root)"
35		profiles=
36		for cmd in $TST_NEEDS_CMDS; do
37			tst_selinux_used_profile $cmd && profiles="$cmd $profiles"
38		done
39		[ -z "$profiles" ] && profiles="none"
40		tst_res TINFO "loaded SELinux profiles: $profiles"
41	fi
42}
43
44# Detect whether AppArmor profiles are loaded
45# Return 0: profiles loaded, 1: none profile loaded or AppArmor disabled
46tst_apparmor_enabled()
47{
48	local f="/sys/module/apparmor/parameters/enabled"
49	[ -f "$f" ] && [ "$(cat $f)" = "Y" ]
50}
51
52# Detect whether AppArmor profile for command is enforced
53# tst_apparmor_used_profile CMD
54# Return 0: loaded profile for CMD
55# Return 1: no profile CMD
56tst_apparmor_used_profile()
57{
58	[ $# -eq 1 ] || tst_brk TCONF "usage tst_apparmor_used_profile CMD"
59	local cmd="$1"
60	grep -q "$cmd .*(enforce)" /sys/kernel/security/apparmor/profiles 2>/dev/null
61}
62
63# Detect whether SELinux is enabled in enforcing mode
64# Return 0: enabled in enforcing mode
65# Return 1: enabled in permissive mode or disabled
66tst_selinux_enabled()
67{
68	local f="$(_tst_get_enforce)"
69
70	[ -f "$f" ] && [ "$(cat $f)" = "1" ]
71}
72
73# Detect whether SELinux profile for command is enforced
74# tst_selinux_used_profile CMD
75# Return 0: loaded profile for CMD
76# Return 1: profile for CMD not loaded or seinfo not available
77tst_selinux_used_profile()
78{
79	[ $# -eq 1 ] || tst_brk TCONF "usage tst_selinux_used_profile CMD"
80	local cmd="$1"
81
82	if ! tst_cmd_available seinfo; then
83		if [ -z "$seinfo_warn_printed" ]; then
84			tst_res TINFO "install seinfo to find used SELinux profiles"
85			export seinfo_warn_printed=1
86		fi
87		return 1
88	fi
89	seinfo -t 2>/dev/null | grep -q $cmd
90}
91
92# Try disable AppArmor
93# Return 0: AppArmor disabled
94# Return > 0: failed to disable AppArmor
95tst_disable_apparmor()
96{
97	tst_res TINFO "trying to disable AppArmor (requires super/root)"
98	_tst_require_root
99
100	local f="aa-teardown"
101	local action
102
103	tst_cmd_available $f && { $f >/dev/null; return; }
104	f="/etc/init.d/apparmor"
105	if [ -f "$f" ]; then
106		for action in teardown kill stop; do
107			$f $action >/dev/null 2>&1 && return
108		done
109	fi
110}
111
112# Try disable SELinux
113# Return 0: SELinux disabled
114# Return > 0: failed to disable SELinux
115tst_disable_selinux()
116{
117	tst_res TINFO "trying to disable SELinux (requires super/root)"
118	_tst_require_root
119
120	local f="$(_tst_get_enforce)"
121
122	[ -f "$f" ] && cat 0 > $f
123}
124
125# Get SELinux enforce file path
126_tst_get_enforce()
127{
128	local dir="/sys/fs/selinux"
129
130	[ -d "$dir" ] || dir="/selinux"
131	local f="$dir/enforce"
132	[ -f "$f" ] && echo "$f"
133}
134