[LTP] [PATCH v3 2/6] shell: Add tst_security.sh helper

Alexey Kodanev alexey.kodanev@oracle.com
Wed Dec 19 13:38:48 CET 2018


Hi Petr,
On 12/18/2018 04:02 AM, Petr Vorel wrote:
> It prints info about AppArmor and SELinux and allows to disable it.
> This is due some false positives because improper usage or bugs
> in AppArmor profiles (e.g. traceroute, dnsmasq).
> 
> Signed-off-by: Petr Vorel <pvorel@suse.cz>
> ---
> NOTE: some of functions in tst_security.sh are meant to be used
> also in tests (when AppArmor and SELinux has different paths).
> ---
>  testcases/lib/tst_security.sh | 124 ++++++++++++++++++++++++++++++++++
>  testcases/lib/tst_test.sh     |  17 +++--
>  2 files changed, 136 insertions(+), 5 deletions(-)
>  create mode 100644 testcases/lib/tst_security.sh
> 
> diff --git a/testcases/lib/tst_security.sh b/testcases/lib/tst_security.sh
> new file mode 100644
> index 000000000..68b47347f
> --- /dev/null
> +++ b/testcases/lib/tst_security.sh
> @@ -0,0 +1,124 @@
> +#!/bin/sh
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# Copyright (c) 2018 Petr Vorel <pvorel@suse.cz>
> +
> +if [ -z "$TST_LIB_LOADED" ]; then
> +	echo "please load tst_test.sh first" >&2
> +	exit 1
> +fi
> +
> +[ -n "$TST_SECURITY_LOADED" ] && return 0
> +TST_SECURITY_LOADED=1
> +
> +_tst_check_security_modules()
> +{
> +	local cmd
> +	local profiles
> +
> +	if tst_apparmor_enabled; then
> +		tst_res TINFO "AppArmor enabled, this may affect test results. Disable it with TST_DISABLE_APPARMOR=1 (requires super/root)"
> +		profiles=
> +		for cmd in $TST_NEEDS_CMDS; do
> +			tst_apparmor_used_profile $cmd && profiles="$cmd $profiles"
> +		done
> +		[ -z "$profiles" ] && profiles="none"
> +		tst_res TINFO "loaded AppArmor profiles: $profiles"
> +	fi
> +
> +	if tst_selinux_enabled; then
> +		tst_res TINFO "SELinux enabled in enforcing mode, this may affect test results. Disable it with TST_DISABLE_SELINUX=1 (requires super/root)"
> +		profiles=
> +		for cmd in $TST_NEEDS_CMDS; do
> +			tst_selinux_used_profile $cmd && profiles="$cmd $profiles"
> +		done
> +		[ -z "$profiles" ] && profiles="none"
> +		tst_res TINFO "loaded SELinux profiles: $profiles"
> +	fi
> +}
> +
> +# Detect whether AppArmor profiles are loaded
> +# Return 0: profiles loaded, 1: none profile loaded or AppArmor disabled
> +tst_apparmor_enabled()
> +{
> +	local f="/sys/module/apparmor/parameters/enabled"
> +	[ -f "$f" ] && [ "$(cat $f)" = "Y" ]
> +}
> +
> +# Detect whether AppArmor profile for command is enforced
> +# tst_apparmor_used_profile CMD
> +# Return 0: loaded profile for CMD
> +# Return 1: no profile CMD
> +tst_apparmor_used_profile()
> +{
> +	[ $# -eq 1 ] && tst_brk TCONF "usage tst_apparmor_used_profile CMD"
              ^
Should be "-ne", because you expect exactly one argument or change the return check to ||.

> +	local cmd="$1"
> +	grep -q "$cmd .*(enforce)" /sys/kernel/security/apparmor/profiles 2>/dev/null
> +}
> +
> +# Detect whether SELinux is enabled in enforcing mode
> +# Return 0: enabled in enforcing mode
> +# Return 1: enabled in permissive mode or disabled
> +tst_selinux_enabled()
> +{
> +	local f="$(_tst_get_enforce)"
> +
> +	[ -f "$f" ] && [ "$(cat $f)" = "1" ]
> +}
> +
> +# Detect whether SELinux profile for command is enforced
> +# tst_selinux_used_profile CMD
> +# Return 0: loaded profile for CMD
> +# Return 1: profile for CMD not loaded or seinfo not available
> +tst_selinux_used_profile()
> +{
> +	[ $# -eq 1 ] && tst_brk TCONF "usage tst_selinux_used_profile CMD"

              ^
     The same is here.


> +	local cmd="$1"
> +
> +	if ! tst_cmd_available seinfo; then
> +		if [ -z "$seinfo_warn_printed" ]; then
> +			tst_res "install seinfo to find used SELinux profiles"
                               ^
                   Please add TINFO.


> +			export seinfo_warn_printed=1
> +		fi
> +		return
                       ^
Missed "return 1" here as you're checking the return value in
_tst_check_security_modules().

> +	fi
> +	seinfo -t 2>/dev/null | grep -q $cmd
> +}
> +
> +# Try disable AppArmor
> +# Return 0: AppArmor disabled
> +# Return > 0: failed to disable AppArmor
> +tst_disable_apparmor()
> +{
> +	_tst_require_root
> +	local f="aa-teardown"
> +	local action
> +
> +	tst_cmd_available $f && { $f; return; }
> +	f="/etc/init.d/apparmor"
> +	if [ -f "$f" ]; then
> +		for action in teardown kill stop; do
> +			$f $action >/dev/null 2>&1 && return
> +		done
> +	fi
> +}
> +
> +# Try disable SELinux
> +# Return 0: SELinux disabled
> +# Return > 0: failed to disable SELinux
> +tst_disable_selinux()
> +{
> +	_tst_require_root
> +	local f="$(_tst_get_enforce)"
> +
> +	[ -f "$f" ] && cat 0 > $f
> +}
> +
> +# Get SELinux enforce file path
> +_tst_get_enforce()
> +{
> +	local dir="/sys/fs/selinux"
> +
> +	[ -d "$dir" ] || dir="/selinux"
> +	local f="$dir/enforce"
> +	[ -f "$f" ] && echo "$f"
> +}
> diff --git a/testcases/lib/tst_test.sh b/testcases/lib/tst_test.sh
> index e3770d005..333061028 100644
> --- a/testcases/lib/tst_test.sh
> +++ b/testcases/lib/tst_test.sh
> @@ -34,6 +34,7 @@ export TST_TMPDIR_RHOST=0
>  export TST_LIB_LOADED=1
>  
>  . tst_ansi_color.sh
> +. tst_security.sh
>  
>  # default trap function
>  trap "tst_brk TBROK 'test interrupted'" INT
> @@ -67,6 +68,7 @@ _tst_do_exit()
>  
>  	if [ $TST_FAIL -gt 0 ]; then
>  		ret=$((ret|1))
> +		_tst_check_security_modules
>  	fi
>  
>  	if [ $TST_BROK -gt 0 ]; then
> @@ -376,6 +378,11 @@ _tst_setup_timer()
>  	_tst_setup_timer_pid=$!
>  }
>  
> +_tst_require_root()
> +{
> +	[ "$(id -ru)" != 0 ] && tst_brk TCONF "Must be super/root for this test!"
> +}
> +
>  tst_run()
>  {
>  	local _tst_i
> @@ -386,6 +393,7 @@ tst_run()
>  	if [ -n "$TST_TEST_PATH" ]; then
>  		for _tst_i in $(grep TST_ "$TST_TEST_PATH" | sed 's/.*TST_//; s/[="} \t\/:`].*//'); do
>  			case "$_tst_i" in
> +			DISABLE_APPARMOR|DISABLE_SELINUX);;
>  			SETUP|CLEANUP|TESTFUNC|ID|CNT|MIN_KVER);;
>  			OPTS|USAGE|PARSE_ARGS|POS_ARGS);;
>  			NEEDS_ROOT|NEEDS_TMPDIR|TMPDIR|NEEDS_DEVICE|DEVICE);;
> @@ -421,11 +429,10 @@ tst_run()
>  		tst_brk TBROK "Number of iterations (-i) must be > 0"
>  	fi
>  
> -	if [ "$TST_NEEDS_ROOT" = 1 ]; then
> -		if [ "$(id -ru)" != 0 ]; then
> -			tst_brk TCONF "Must be super/root for this test!"
> -		fi
> -	fi
> +	[ "$TST_NEEDS_ROOT" = 1 ] && _tst_require_root
> +
> +	[ "$TST_DISABLE_APPARMOR" = 1 ] && tst_disable_apparmor
> +	[ "$TST_DISABLE_SELINUX" = 1 ] && tst_disable_selinux
>  
>  	tst_test_cmds $TST_NEEDS_CMDS
>  	tst_test_drivers $TST_NEEDS_DRIVERS
> 

The rest in the patch-set looks fine to me.

Thanks,
Alexey


More information about the ltp mailing list