diff mbox series

[v3,05/10] IMA: Read required policy from file

Message ID 20250114112915.610297-6-pvorel@suse.cz (mailing list archive)
State New
Headers show
Series LTP tests: load predefined policy, enhancements | expand

Commit Message

Petr Vorel Jan. 14, 2025, 11:29 a.m. UTC
Previously snipped of required policy was as a string or regexp.
Loading required policy from file allows to move code to ima_setup.sh.
This is a preparation for loading IMA policy from file.

Check can be done on one or both:
1) IMA builtin policy (based on /proc/cmdline)
2) IMA policy content (actual content of /sys/kernel/security/ima/policy)

When missing CONFIG_IMA_READ_POLICY=y on required policy convert: test, but convert TFAIL => TCONF.

Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
 .../security/integrity/ima/tests/ima_kexec.sh | 19 ++----
 .../security/integrity/ima/tests/ima_keys.sh  | 47 ++++---------
 .../integrity/ima/tests/ima_measurements.sh   |  8 ++-
 .../integrity/ima/tests/ima_selinux.sh        | 22 +++---
 .../security/integrity/ima/tests/ima_setup.sh | 68 ++++++++++++++-----
 .../integrity/ima/tests/ima_violations.sh     |  8 ++-
 6 files changed, 92 insertions(+), 80 deletions(-)

Comments

Mimi Zohar Jan. 23, 2025, 5:39 p.m. UTC | #1
On Tue, 2025-01-14 at 12:29 +0100, Petr Vorel wrote:
> Previously snipped of required policy was as a string or regexp.
> Loading required policy from file allows to move code to ima_setup.sh.
> This is a preparation for loading IMA policy from file.
> 
> Check can be done on one or both:
> 1) IMA builtin policy (based on /proc/cmdline)
> 2) IMA policy content (actual content of /sys/kernel/security/ima/policy)
> 
> When missing CONFIG_IMA_READ_POLICY=y on required policy convert: test, but convert
> TFAIL => TCONF.
> 
> Signed-off-by: Petr Vorel <pvorel@suse.cz>

Thanks, Petr.  Really nice patch.  Below is an improvement suggestion.

Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>

> ---
> 
> diff --git a/testcases/kernel/security/integrity/ima/tests/ima_selinux.sh
> b/testcases/kernel/security/integrity/ima/tests/ima_selinux.sh
> index 75f9ba84e4..45fd741b5f 100755
> --- a/testcases/kernel/security/integrity/ima/tests/ima_selinux.sh
> +++ b/testcases/kernel/security/integrity/ima/tests/ima_selinux.sh
> @@ -1,6 +1,7 @@
>  #!/bin/sh
>  # SPDX-License-Identifier: GPL-2.0-or-later
>  # Copyright (c) 2021 Microsoft Corporation
> +# Copyright (c) Linux Test Project, 2021-2025
>  # Author: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
>  #
>  # Verify measurement of SELinux policy hash and state.
> @@ -14,15 +15,12 @@ TST_CNT=2
>  TST_SETUP="setup"
>  TST_MIN_KVER="5.12"
>  
> -FUNC_CRITICAL_DATA='func=CRITICAL_DATA'
> -REQUIRED_POLICY="^measure.*$FUNC_CRITICAL_DATA"
> +REQUIRED_POLICY_CONTENT='selinux.policy'

The selinux.policy contains a specific critical data measurement rule:
measure func=CRITICAL_DATA label=selinux.  However the test would work with the
generic policy rule "measure func=CRITICAL_DATA", which can be specified on the . 
boot command line via "ima_policy=critical_data".

As long as being able to read the IMA policy is required, in addition to checking
whether the specific critical data rule exists, check whether the generic rule exists
before loading the specific one.

Perhaps all that is needed is defining REQUIRED_BUILTIN_POLICY like:
REQUIRED_BUILTIN_POLICY="critical_data"

>  
>  setup()
>  {
>  	SELINUX_DIR=$(tst_get_selinux_dir)
>  	[ "$SELINUX_DIR" ] || tst_brk TCONF "SELinux is not enabled"
> -
> -	require_ima_policy_content "$REQUIRED_POLICY" '-E' >
> $TST_TMPDIR/policy.txt
>  }
>  
>  # Format of the measured SELinux state data.
> @@ -45,7 +43,7 @@ validate_policy_capabilities()
>  		measured_value=$(echo $1 | awk -F'[=;]' -v inx="$inx" '{print
> $inx}')
>  		expected_value=$(cat
> "$SELINUX_DIR/policy_capabilities/$measured_cap")
>  		if [ "$measured_value" != "$expected_value" ]; then
> -			tst_res TFAIL "$measured_cap: expected: $expected_value,
> got: $digest"
> +			tst_res $IMA_FAIL "$measured_cap: expected:
> $expected_value, got: $digest"
>  			return
>  		fi
>  
> @@ -75,7 +73,7 @@ test1()
>  	# in kernel memory for SELinux
>  	line=$(grep -E "selinux-policy-hash" $ASCII_MEASUREMENTS | tail -1)
>  	if [ -z "$line" ]; then
> -		tst_res TFAIL "SELinux policy hash not measured"
> +		tst_res $IMA_FAIL "SELinux policy hash not measured"
>  		return
>  	fi
>  
> @@ -86,7 +84,7 @@ test1()
>  		tst_brk TCONF "cannot compute digest for $algorithm"
>  
>  	if [ "$policy_digest" != "$expected_policy_digest" ]; then
> -		tst_res TFAIL "Digest mismatch: expected: $expected_policy_digest,
> got: $policy_digest"
> +		tst_res $IMA_FAIL "Digest mismatch: expected:
> $expected_policy_digest, got: $policy_digest"
>  		return
>  	fi
>  
> @@ -116,7 +114,7 @@ test2()
>  	# state matches that currently set for SELinux
>  	line=$(grep -E "selinux-state" $ASCII_MEASUREMENTS | tail -1)
>  	if [ -z "$line" ]; then
> -		tst_res TFAIL "SELinux state not measured"
> +		tst_res $IMA_FAIL "SELinux state not measured"
>  		return
>  	fi
>  
> @@ -129,7 +127,7 @@ test2()
>  	tst_brk TCONF "cannot compute digest for $algorithm"
>  
>  	if [ "$digest" != "$expected_digest" ]; then
> -		tst_res TFAIL "digest mismatch: expected: $expected_digest, got:
> $digest"
> +		tst_res $IMA_FAIL "digest mismatch: expected: $expected_digest,
> got: $digest"
>  		return
>  	fi
>  
> @@ -146,20 +144,20 @@ test2()
>  	enforced_value=$(echo $measured_data | awk -F'[=;]' '{print $4}')
>  	expected_enforced_value=$(cat $SELINUX_DIR/enforce)
>  	if [ "$expected_enforced_value" != "$enforced_value" ]; then
> -		tst_res TFAIL "enforce: expected: $expected_enforced_value, got:
> $enforced_value"
> +		tst_res $IMA_FAIL "enforce: expected: $expected_enforced_value,
> got: $enforced_value"
>  		return
>  	fi
>  
>  	checkreqprot_value=$(echo $measured_data | awk -F'[=;]' '{print $6}')
>  	expected_checkreqprot_value=$(cat $SELINUX_DIR/checkreqprot)
>  	if [ "$expected_checkreqprot_value" != "$checkreqprot_value" ]; then
> -		tst_res TFAIL "checkreqprot: expected:
> $expected_checkreqprot_value, got: $checkreqprot_value"
> +		tst_res $IMA_FAIL "checkreqprot: expected:
> $expected_checkreqprot_value, got: $checkreqprot_value"
>  		return
>  	fi
>  
>  	initialized_value=$(echo $measured_data | awk -F'[=;]' '{print $2}')
>  	if [ "$initialized_value" != "1" ]; then
> -		tst_res TFAIL "initialized: expected 1, got: $initialized_value"
> +		tst_res $IMA_FAIL "initialized: expected 1, got:
> $initialized_value"
>  		return
>  	fi
diff mbox series

Patch

diff --git a/testcases/kernel/security/integrity/ima/tests/ima_kexec.sh b/testcases/kernel/security/integrity/ima/tests/ima_kexec.sh
index 3446bc24bf..95e6186bb5 100755
--- a/testcases/kernel/security/integrity/ima/tests/ima_kexec.sh
+++ b/testcases/kernel/security/integrity/ima/tests/ima_kexec.sh
@@ -1,7 +1,7 @@ 
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0-or-later
 # Copyright (c) 2020 Microsoft Corporation
-# Copyright (c) 2020 Petr Vorel <pvorel@suse.cz>
+# Copyright (c) 2020-2025 Petr Vorel <pvorel@suse.cz>
 # Author: Lachlan Sneff <t-josne@linux.microsoft.com>
 #
 # Verify that kexec cmdline is measured correctly.
@@ -14,7 +14,7 @@  TST_SETUP="setup"
 TST_MIN_KVER="5.3"
 
 IMA_KEXEC_IMAGE="${IMA_KEXEC_IMAGE:-/boot/vmlinuz-$(uname -r)}"
-REQUIRED_POLICY='^measure.*func=KEXEC_CMDLINE'
+REQUIRED_POLICY_CONTENT='kexec.policy'
 
 measure()
 {
@@ -46,11 +46,6 @@  setup()
 	if [ ! -f "$IMA_KEXEC_IMAGE" ]; then
 		tst_brk TCONF "kernel image not found, specify path in \$IMA_KEXEC_IMAGE"
 	fi
-
-	if check_policy_readable; then
-		require_ima_policy_content "$REQUIRED_POLICY"
-		policy_readable=1
-	fi
 }
 
 kexec_failure_hint()
@@ -79,7 +74,6 @@  kexec_test()
 {
 	local param="$1"
 	local cmdline="$2"
-	local res=TFAIL
 	local kexec_cmd
 
 	kexec_cmd="$param=$cmdline"
@@ -97,13 +91,10 @@  kexec_test()
 
 	ROD kexec -su
 	if ! measure "$cmdline"; then
-		if [ "$policy_readable" != 1 ]; then
-			tst_res TWARN "policy not readable, it might not contain required policy '$REQUIRED_POLICY'"
-			res=TBROK
-		fi
-		tst_brk $res "unable to find a correct measurement"
+		tst_res $IMA_FAIL "unable to find a correct measurement"
+	else
+		tst_res TPASS "kexec cmdline was measured correctly"
 	fi
-	tst_res TPASS "kexec cmdline was measured correctly"
 }
 
 test()
diff --git a/testcases/kernel/security/integrity/ima/tests/ima_keys.sh b/testcases/kernel/security/integrity/ima/tests/ima_keys.sh
index ff32eb6c43..a2e9c77738 100755
--- a/testcases/kernel/security/integrity/ima/tests/ima_keys.sh
+++ b/testcases/kernel/security/integrity/ima/tests/ima_keys.sh
@@ -1,7 +1,7 @@ 
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0-or-later
 # Copyright (c) 2020 Microsoft Corporation
-# Copyright (c) 2020-2021 Petr Vorel <pvorel@suse.cz>
+# Copyright (c) 2020-2025 Petr Vorel <pvorel@suse.cz>
 # Author: Lachlan Sneff <t-josne@linux.microsoft.com>
 #
 # Verify that keys are measured correctly based on policy.
@@ -12,38 +12,24 @@  TST_SETUP=setup
 TST_CLEANUP=cleanup
 TST_MIN_KVER="5.6"
 
-FUNC_KEYCHECK='func=KEY_CHECK'
-REQUIRED_POLICY="^measure.*$FUNC_KEYCHECK"
+REQUIRED_POLICY_CONTENT='keycheck.policy'
 
 setup()
 {
-	require_ima_policy_content "$REQUIRED_POLICY" '-E' > $TST_TMPDIR/policy.txt
-	require_valid_policy_template
-}
+	local line
 
-cleanup()
-{
-	tst_is_num $KEYRING_ID && keyctl clear $KEYRING_ID
-}
+	require_policy_readable
 
-require_valid_policy_template()
-{
 	while read line; do
-	if echo $line | grep -q 'template=' && ! echo $line | grep -q 'template=ima-buf'; then
-		tst_brk TCONF "only template=ima-buf can be specified for KEY_CHECK"
-	fi
-	done < $TST_TMPDIR/policy.txt
+		if echo $line | grep -q 'template=' && ! echo $line | grep -q 'template=ima-buf'; then
+			tst_brk TCONF "only template=ima-buf can be specified for KEY_CHECK"
+		fi
+	done < $IMA_POLICY
 }
 
-check_keys_policy()
+cleanup()
 {
-	local pattern="$1"
-
-	if ! grep -E "$pattern" $TST_TMPDIR/policy.txt; then
-		tst_res TCONF "IMA policy must specify $pattern, $FUNC_KEYCHECK"
-		return 1
-	fi
-	return 0
+	tst_is_num $KEYRING_ID && keyctl clear $KEYRING_ID
 }
 
 # Based on https://lkml.org/lkml/2019/12/13/564.
@@ -51,12 +37,10 @@  check_keys_policy()
 test1()
 {
 	local keycheck_lines i keyrings templates
-	local pattern='keyrings=[^[:space:]]+'
 	local test_file="file.txt" tmp_file="file2.txt"
 
 	tst_res TINFO "verify key measurement for keyrings and templates specified in IMA policy"
 
-	check_keys_policy "$pattern" > $tmp_file || return
 	keycheck_lines=$(cat $tmp_file)
 	keyrings=$(for i in $keycheck_lines; do echo "$i" | grep "keyrings" | \
 		sed "s/\./\\\./g" | cut -d'=' -f2; done | sed ':a;N;$!ba;s/\n/|/g')
@@ -87,7 +71,7 @@  test1()
 		fi
 
 		if [ "$digest" != "$expected_digest" ]; then
-			tst_res TFAIL "incorrect digest was found for $keyring keyring"
+			tst_res $IMA_FAIL "incorrect digest was found for $keyring keyring"
 			return
 		fi
 	done
@@ -105,13 +89,10 @@  test2()
 
 	local cert_file="$TST_DATAROOT/x509_ima.der"
 	local keyring_name="key_import_test"
-	local pattern="keyrings=[^[:space:]]*$keyring_name"
 	local temp_file="file.txt"
 
 	tst_res TINFO "verify measurement of certificate imported into a keyring"
 
-	check_keys_policy "$pattern" >/dev/null || return
-
 	KEYRING_ID=$(keyctl newring $keyring_name @s) || \
 		tst_brk TBROK "unable to create a new keyring"
 
@@ -126,19 +107,19 @@  test2()
 		tst_hexdump -d > $temp_file
 
 	if [ ! -s $temp_file ]; then
-		tst_res TFAIL "keyring $keyring_name not found in $ASCII_MEASUREMENTS"
+		tst_res $IMA_FAIL "keyring $keyring_name not found in $ASCII_MEASUREMENTS"
 		return
 	fi
 
 	if ! openssl x509 -in $temp_file -inform der > /dev/null; then
-		tst_res TFAIL "logged certificate is not a valid x509 certificate"
+		tst_res $IMA_FAIL "logged certificate is not a valid x509 certificate"
 		return
 	fi
 
 	if cmp -s $temp_file $cert_file; then
 		tst_res TPASS "logged certificate matches the original"
 	else
-		tst_res TFAIL "logged certificate does not match original"
+		tst_res $IMA_FAIL "logged certificate does not match original"
 	fi
 }
 
diff --git a/testcases/kernel/security/integrity/ima/tests/ima_measurements.sh b/testcases/kernel/security/integrity/ima/tests/ima_measurements.sh
index ca9d73b4aa..41d53aa03b 100755
--- a/testcases/kernel/security/integrity/ima/tests/ima_measurements.sh
+++ b/testcases/kernel/security/integrity/ima/tests/ima_measurements.sh
@@ -11,6 +11,7 @@  TST_NEEDS_CMDS="awk cut sed"
 TST_SETUP="setup"
 TST_CNT=3
 REQUIRED_BUILTIN_POLICY="tcb"
+REQUIRED_POLICY_CONTENT='tcb.policy'
 
 setup()
 {
@@ -70,6 +71,7 @@  test3()
 	local user="nobody"
 	local dir="$PWD/user"
 	local file="$dir/test.txt"
+	local cmd="grep $file $ASCII_MEASUREMENTS"
 
 	# Default policy does not measure user files
 	tst_res TINFO "verify not measuring user files"
@@ -87,7 +89,11 @@  test3()
 	sudo -n -u $user sh -c "echo $(cat /proc/uptime) user file > $file; cat $file > /dev/null"
 	cd ..
 
-	EXPECT_FAIL "grep $file $ASCII_MEASUREMENTS"
+	if tst_rod "$cmd" 2> /dev/null; then
+		tst_res TPASS "$cmd failed as expected"
+	else
+		tst_res $IMA_FAIL "$cmd passed unexpectedly"
+	fi
 }
 
 . ima_setup.sh
diff --git a/testcases/kernel/security/integrity/ima/tests/ima_selinux.sh b/testcases/kernel/security/integrity/ima/tests/ima_selinux.sh
index 75f9ba84e4..45fd741b5f 100755
--- a/testcases/kernel/security/integrity/ima/tests/ima_selinux.sh
+++ b/testcases/kernel/security/integrity/ima/tests/ima_selinux.sh
@@ -1,6 +1,7 @@ 
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0-or-later
 # Copyright (c) 2021 Microsoft Corporation
+# Copyright (c) Linux Test Project, 2021-2025
 # Author: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
 #
 # Verify measurement of SELinux policy hash and state.
@@ -14,15 +15,12 @@  TST_CNT=2
 TST_SETUP="setup"
 TST_MIN_KVER="5.12"
 
-FUNC_CRITICAL_DATA='func=CRITICAL_DATA'
-REQUIRED_POLICY="^measure.*$FUNC_CRITICAL_DATA"
+REQUIRED_POLICY_CONTENT='selinux.policy'
 
 setup()
 {
 	SELINUX_DIR=$(tst_get_selinux_dir)
 	[ "$SELINUX_DIR" ] || tst_brk TCONF "SELinux is not enabled"
-
-	require_ima_policy_content "$REQUIRED_POLICY" '-E' > $TST_TMPDIR/policy.txt
 }
 
 # Format of the measured SELinux state data.
@@ -45,7 +43,7 @@  validate_policy_capabilities()
 		measured_value=$(echo $1 | awk -F'[=;]' -v inx="$inx" '{print $inx}')
 		expected_value=$(cat "$SELINUX_DIR/policy_capabilities/$measured_cap")
 		if [ "$measured_value" != "$expected_value" ]; then
-			tst_res TFAIL "$measured_cap: expected: $expected_value, got: $digest"
+			tst_res $IMA_FAIL "$measured_cap: expected: $expected_value, got: $digest"
 			return
 		fi
 
@@ -75,7 +73,7 @@  test1()
 	# in kernel memory for SELinux
 	line=$(grep -E "selinux-policy-hash" $ASCII_MEASUREMENTS | tail -1)
 	if [ -z "$line" ]; then
-		tst_res TFAIL "SELinux policy hash not measured"
+		tst_res $IMA_FAIL "SELinux policy hash not measured"
 		return
 	fi
 
@@ -86,7 +84,7 @@  test1()
 		tst_brk TCONF "cannot compute digest for $algorithm"
 
 	if [ "$policy_digest" != "$expected_policy_digest" ]; then
-		tst_res TFAIL "Digest mismatch: expected: $expected_policy_digest, got: $policy_digest"
+		tst_res $IMA_FAIL "Digest mismatch: expected: $expected_policy_digest, got: $policy_digest"
 		return
 	fi
 
@@ -116,7 +114,7 @@  test2()
 	# state matches that currently set for SELinux
 	line=$(grep -E "selinux-state" $ASCII_MEASUREMENTS | tail -1)
 	if [ -z "$line" ]; then
-		tst_res TFAIL "SELinux state not measured"
+		tst_res $IMA_FAIL "SELinux state not measured"
 		return
 	fi
 
@@ -129,7 +127,7 @@  test2()
 	tst_brk TCONF "cannot compute digest for $algorithm"
 
 	if [ "$digest" != "$expected_digest" ]; then
-		tst_res TFAIL "digest mismatch: expected: $expected_digest, got: $digest"
+		tst_res $IMA_FAIL "digest mismatch: expected: $expected_digest, got: $digest"
 		return
 	fi
 
@@ -146,20 +144,20 @@  test2()
 	enforced_value=$(echo $measured_data | awk -F'[=;]' '{print $4}')
 	expected_enforced_value=$(cat $SELINUX_DIR/enforce)
 	if [ "$expected_enforced_value" != "$enforced_value" ]; then
-		tst_res TFAIL "enforce: expected: $expected_enforced_value, got: $enforced_value"
+		tst_res $IMA_FAIL "enforce: expected: $expected_enforced_value, got: $enforced_value"
 		return
 	fi
 
 	checkreqprot_value=$(echo $measured_data | awk -F'[=;]' '{print $6}')
 	expected_checkreqprot_value=$(cat $SELINUX_DIR/checkreqprot)
 	if [ "$expected_checkreqprot_value" != "$checkreqprot_value" ]; then
-		tst_res TFAIL "checkreqprot: expected: $expected_checkreqprot_value, got: $checkreqprot_value"
+		tst_res $IMA_FAIL "checkreqprot: expected: $expected_checkreqprot_value, got: $checkreqprot_value"
 		return
 	fi
 
 	initialized_value=$(echo $measured_data | awk -F'[=;]' '{print $2}')
 	if [ "$initialized_value" != "1" ]; then
-		tst_res TFAIL "initialized: expected 1, got: $initialized_value"
+		tst_res $IMA_FAIL "initialized: expected 1, got: $initialized_value"
 		return
 	fi
 
diff --git a/testcases/kernel/security/integrity/ima/tests/ima_setup.sh b/testcases/kernel/security/integrity/ima/tests/ima_setup.sh
index 2a578ceb45..af5584951c 100644
--- a/testcases/kernel/security/integrity/ima/tests/ima_setup.sh
+++ b/testcases/kernel/security/integrity/ima/tests/ima_setup.sh
@@ -19,6 +19,9 @@  SYSFS="/sys"
 UMOUNT=
 TST_FS_TYPE="ext3"
 
+IMA_FAIL="TFAIL"
+IMA_BROK="TBROK"
+
 # TODO: find support for rmd128 rmd256 rmd320 wp256 wp384 tgr128 tgr160
 compute_digest()
 {
@@ -85,21 +88,9 @@  require_policy_writable()
 check_ima_policy_content()
 {
 	local pattern="$1"
-	local grep_params="${2--q}"
 
 	check_policy_readable || return 1
-	grep $grep_params "$pattern" $IMA_POLICY
-}
-
-require_ima_policy_content()
-{
-	local pattern="$1"
-	local grep_params="${2--q}"
-
-	require_policy_readable
-	if ! grep $grep_params "$pattern" $IMA_POLICY; then
-		tst_brk TCONF "IMA policy does not specify '$pattern'"
-	fi
+	grep -q "$pattern" $IMA_POLICY
 }
 
 check_ima_policy_cmdline()
@@ -158,6 +149,51 @@  print_ima_config()
 	tst_res TINFO "/proc/cmdline: $(cat /proc/cmdline)"
 }
 
+# Check for required
+# 1) IMA builtin policy (based on /proc/cmdline)
+# 2) IMA policy content (actual content of /sys/kernel/security/ima/policy)
+# When missing CONFIG_IMA_READ_POLICY=y on required policy convert: test, but convert TFAIL => TCONF.
+# $REQUIRED_POLICY_CONTENT: file with required IMA policy
+# $REQUIRED_BUILTIN_POLICY: IMA policy specified as kernel cmdline
+verify_ima_policy()
+{
+	local check_content line
+	local file="$TST_DATAROOT/$REQUIRED_POLICY_CONTENT"
+
+	if [ -z "$REQUIRED_POLICY_CONTENT" -a -z "$REQUIRED_BUILTIN_POLICY" ]; then
+		return 0
+	fi
+
+	if [ -n "$REQUIRED_POLICY_CONTENT" ]; then
+		check_content=1
+		if [ -n "$REQUIRED_BUILTIN_POLICY" ] && check_ima_policy_cmdline "$REQUIRED_BUILTIN_POLICY"; then
+			tst_res TINFO "booted with IMA policy: $REQUIRED_BUILTIN_POLICY"
+			return 0
+		fi
+	elif [ -n "$REQUIRED_BUILTIN_POLICY" ]; then
+		require_ima_policy_cmdline "$REQUIRED_BUILTIN_POLICY"
+	fi
+
+	if [ "$check_content" = 1 ]; then
+		[ -e $file ] || tst_brk TBROK "policy file '$file' does not exist (LTPROOT=$LTPROOT)"
+		tst_res TINFO "test requires IMA policy:"
+		cat $file
+		if check_policy_readable; then
+			# check IMA policy content
+			while read line; do
+				if ! grep -q "$line" $IMA_POLICY; then
+					tst_brk TCONF "missing required policy '$line'"
+				fi
+				IMA_POLICY_CHECKED=1
+			done < $file
+		else
+			tst_res TINFO "policy is not readable, failure will be treated as TCONF"
+			IMA_FAIL="TCONF"
+			IMA_BROK="TCONF"
+		fi
+	fi
+}
+
 ima_setup()
 {
 	SECURITYFS="$(mount_helper securityfs $SYSFS/kernel/security)"
@@ -180,9 +216,7 @@  ima_setup()
 		cd "$TST_MNTPOINT"
 	fi
 
-	if [ "$REQUIRED_BUILTIN_POLICY" ]; then
-		require_ima_policy_cmdline "$REQUIRED_BUILTIN_POLICY"
-	fi
+	verify_ima_policy
 
 	[ -n "$TST_SETUP_CALLER" ] && $TST_SETUP_CALLER
 }
@@ -290,7 +324,7 @@  ima_check()
 		algorithm=$(cat tmp | cut -d'|' -f1)
 		digest=$(cat tmp | cut -d'|' -f2)
 	else
-		tst_brk TBROK "failed to get algorithm/digest for '$test_file'"
+		tst_brk $IMA_BROK "failed to get algorithm/digest for '$test_file'"
 	fi
 
 	tst_res TINFO "computing digest for $algorithm algorithm"
diff --git a/testcases/kernel/security/integrity/ima/tests/ima_violations.sh b/testcases/kernel/security/integrity/ima/tests/ima_violations.sh
index b2b597ad08..1852e8bc74 100755
--- a/testcases/kernel/security/integrity/ima/tests/ima_violations.sh
+++ b/testcases/kernel/security/integrity/ima/tests/ima_violations.sh
@@ -1,7 +1,7 @@ 
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0-or-later
 # Copyright (c) 2009 IBM Corporation
-# Copyright (c) 2018-2020 Petr Vorel <pvorel@suse.cz>
+# Copyright (c) 2018-2025 Petr Vorel <pvorel@suse.cz>
 # Author: Mimi Zohar <zohar@linux.ibm.com>
 #
 # Test whether ToMToU and open_writer violations invalidatethe PCR and are logged.
@@ -10,6 +10,8 @@  TST_SETUP="setup"
 TST_CLEANUP="cleanup"
 TST_CNT=3
 
+REQUIRED_POLICY_CONTENT='violations.policy'
+
 setup()
 {
 	FILE="test.txt"
@@ -83,11 +85,11 @@  validate()
 				tst_sleep 1s
 			fi
 		else
-			tst_res TFAIL "$search violation not added"
+			tst_res $IMA_FAIL "$search violation not added"
 			return
 		fi
 	done
-	tst_res TFAIL "$search not found in $LOG"
+	tst_res $IMA_FAIL "$search not found in $LOG"
 }
 
 test1()