Skip to content

Commit 4c74c7d

Browse files
committed
IMA: Read required policy from file
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. Link: https://lore.kernel.org/ltp/[email protected]/ Reviewed-by: Mimi Zohar <[email protected]> Signed-off-by: Petr Vorel <[email protected]>
1 parent 3089191 commit 4c74c7d

File tree

6 files changed

+92
-80
lines changed

6 files changed

+92
-80
lines changed

testcases/kernel/security/integrity/ima/tests/ima_kexec.sh

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/sh
22
# SPDX-License-Identifier: GPL-2.0-or-later
33
# Copyright (c) 2020 Microsoft Corporation
4-
# Copyright (c) 2020 Petr Vorel <[email protected]>
4+
# Copyright (c) 2020-2025 Petr Vorel <[email protected]>
55
# Author: Lachlan Sneff <[email protected]>
66
#
77
# Verify that kexec cmdline is measured correctly.
@@ -14,7 +14,7 @@ TST_SETUP="setup"
1414
TST_MIN_KVER="5.3"
1515

1616
IMA_KEXEC_IMAGE="${IMA_KEXEC_IMAGE:-/boot/vmlinuz-$(uname -r)}"
17-
REQUIRED_POLICY='^measure.*func=KEXEC_CMDLINE'
17+
REQUIRED_POLICY_CONTENT='kexec.policy'
1818

1919
measure()
2020
{
@@ -46,11 +46,6 @@ setup()
4646
if [ ! -f "$IMA_KEXEC_IMAGE" ]; then
4747
tst_brk TCONF "kernel image not found, specify path in \$IMA_KEXEC_IMAGE"
4848
fi
49-
50-
if check_policy_readable; then
51-
require_ima_policy_content "$REQUIRED_POLICY"
52-
policy_readable=1
53-
fi
5449
}
5550

5651
kexec_failure_hint()
@@ -79,7 +74,6 @@ kexec_test()
7974
{
8075
local param="$1"
8176
local cmdline="$2"
82-
local res=TFAIL
8377
local kexec_cmd
8478

8579
kexec_cmd="$param=$cmdline"
@@ -97,13 +91,10 @@ kexec_test()
9791

9892
ROD kexec -su
9993
if ! measure "$cmdline"; then
100-
if [ "$policy_readable" != 1 ]; then
101-
tst_res TWARN "policy not readable, it might not contain required policy '$REQUIRED_POLICY'"
102-
res=TBROK
103-
fi
104-
tst_brk $res "unable to find a correct measurement"
94+
tst_res $IMA_FAIL "unable to find a correct measurement"
95+
else
96+
tst_res TPASS "kexec cmdline was measured correctly"
10597
fi
106-
tst_res TPASS "kexec cmdline was measured correctly"
10798
}
10899

109100
test()

testcases/kernel/security/integrity/ima/tests/ima_keys.sh

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/sh
22
# SPDX-License-Identifier: GPL-2.0-or-later
33
# Copyright (c) 2020 Microsoft Corporation
4-
# Copyright (c) 2020-2021 Petr Vorel <[email protected]>
4+
# Copyright (c) 2020-2025 Petr Vorel <[email protected]>
55
# Author: Lachlan Sneff <[email protected]>
66
#
77
# Verify that keys are measured correctly based on policy.
@@ -12,51 +12,35 @@ TST_SETUP=setup
1212
TST_CLEANUP=cleanup
1313
TST_MIN_KVER="5.6"
1414

15-
FUNC_KEYCHECK='func=KEY_CHECK'
16-
REQUIRED_POLICY="^measure.*$FUNC_KEYCHECK"
15+
REQUIRED_POLICY_CONTENT='keycheck.policy'
1716

1817
setup()
1918
{
20-
require_ima_policy_content "$REQUIRED_POLICY" '-E' > $TST_TMPDIR/policy.txt
21-
require_valid_policy_template
22-
}
19+
local line
2320

24-
cleanup()
25-
{
26-
tst_is_num $KEYRING_ID && keyctl clear $KEYRING_ID
27-
}
21+
require_policy_readable
2822

29-
require_valid_policy_template()
30-
{
3123
while read line; do
32-
if echo $line | grep -q 'template=' && ! echo $line | grep -q 'template=ima-buf'; then
33-
tst_brk TCONF "only template=ima-buf can be specified for KEY_CHECK"
34-
fi
35-
done < $TST_TMPDIR/policy.txt
24+
if echo $line | grep -q 'template=' && ! echo $line | grep -q 'template=ima-buf'; then
25+
tst_brk TCONF "only template=ima-buf can be specified for KEY_CHECK"
26+
fi
27+
done < $IMA_POLICY
3628
}
3729

38-
check_keys_policy()
30+
cleanup()
3931
{
40-
local pattern="$1"
41-
42-
if ! grep -E "$pattern" $TST_TMPDIR/policy.txt; then
43-
tst_res TCONF "IMA policy must specify $pattern, $FUNC_KEYCHECK"
44-
return 1
45-
fi
46-
return 0
32+
tst_is_num $KEYRING_ID && keyctl clear $KEYRING_ID
4733
}
4834

4935
# Based on https://lkml.org/lkml/2019/12/13/564.
5036
# (450d0fd51564 - "IMA: Call workqueue functions to measure queued keys")
5137
test1()
5238
{
5339
local keycheck_lines i keyrings templates
54-
local pattern='keyrings=[^[:space:]]+'
5540
local test_file="file.txt" tmp_file="file2.txt"
5641

5742
tst_res TINFO "verify key measurement for keyrings and templates specified in IMA policy"
5843

59-
check_keys_policy "$pattern" > $tmp_file || return
6044
keycheck_lines=$(cat $tmp_file)
6145
keyrings=$(for i in $keycheck_lines; do echo "$i" | grep "keyrings" | \
6246
sed "s/\./\\\./g" | cut -d'=' -f2; done | sed ':a;N;$!ba;s/\n/|/g')
@@ -87,7 +71,7 @@ test1()
8771
fi
8872

8973
if [ "$digest" != "$expected_digest" ]; then
90-
tst_res TFAIL "incorrect digest was found for $keyring keyring"
74+
tst_res $IMA_FAIL "incorrect digest was found for $keyring keyring"
9175
return
9276
fi
9377
done
@@ -105,13 +89,10 @@ test2()
10589

10690
local cert_file="$TST_DATAROOT/x509_ima.der"
10791
local keyring_name="key_import_test"
108-
local pattern="keyrings=[^[:space:]]*$keyring_name"
10992
local temp_file="file.txt"
11093

11194
tst_res TINFO "verify measurement of certificate imported into a keyring"
11295

113-
check_keys_policy "$pattern" >/dev/null || return
114-
11596
KEYRING_ID=$(keyctl newring $keyring_name @s) || \
11697
tst_brk TBROK "unable to create a new keyring"
11798

@@ -126,19 +107,19 @@ test2()
126107
tst_hexdump -d > $temp_file
127108

128109
if [ ! -s $temp_file ]; then
129-
tst_res TFAIL "keyring $keyring_name not found in $ASCII_MEASUREMENTS"
110+
tst_res $IMA_FAIL "keyring $keyring_name not found in $ASCII_MEASUREMENTS"
130111
return
131112
fi
132113

133114
if ! openssl x509 -in $temp_file -inform der > /dev/null; then
134-
tst_res TFAIL "logged certificate is not a valid x509 certificate"
115+
tst_res $IMA_FAIL "logged certificate is not a valid x509 certificate"
135116
return
136117
fi
137118

138119
if cmp -s $temp_file $cert_file; then
139120
tst_res TPASS "logged certificate matches the original"
140121
else
141-
tst_res TFAIL "logged certificate does not match original"
122+
tst_res $IMA_FAIL "logged certificate does not match original"
142123
fi
143124
}
144125

testcases/kernel/security/integrity/ima/tests/ima_measurements.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ TST_NEEDS_CMDS="awk cut sed"
1111
TST_SETUP="setup"
1212
TST_CNT=3
1313
REQUIRED_BUILTIN_POLICY="tcb"
14+
REQUIRED_POLICY_CONTENT='tcb.policy'
1415

1516
setup()
1617
{
@@ -70,6 +71,7 @@ test3()
7071
local user="nobody"
7172
local dir="$PWD/user"
7273
local file="$dir/test.txt"
74+
local cmd="grep $file $ASCII_MEASUREMENTS"
7375

7476
# Default policy does not measure user files
7577
tst_res TINFO "verify not measuring user files"
@@ -87,7 +89,11 @@ test3()
8789
sudo -n -u $user sh -c "echo $(cat /proc/uptime) user file > $file; cat $file > /dev/null"
8890
cd ..
8991

90-
EXPECT_FAIL "grep $file $ASCII_MEASUREMENTS"
92+
if tst_rod "$cmd" 2> /dev/null; then
93+
tst_res TPASS "$cmd failed as expected"
94+
else
95+
tst_res $IMA_FAIL "$cmd passed unexpectedly"
96+
fi
9197
}
9298

9399
. ima_setup.sh

testcases/kernel/security/integrity/ima/tests/ima_selinux.sh

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/bin/sh
22
# SPDX-License-Identifier: GPL-2.0-or-later
33
# Copyright (c) 2021 Microsoft Corporation
4+
# Copyright (c) Linux Test Project, 2021-2025
45
# Author: Lakshmi Ramasubramanian <[email protected]>
56
#
67
# Verify measurement of SELinux policy hash and state.
@@ -14,15 +15,12 @@ TST_CNT=2
1415
TST_SETUP="setup"
1516
TST_MIN_KVER="5.12"
1617

17-
FUNC_CRITICAL_DATA='func=CRITICAL_DATA'
18-
REQUIRED_POLICY="^measure.*$FUNC_CRITICAL_DATA"
18+
REQUIRED_POLICY_CONTENT='selinux.policy'
1919

2020
setup()
2121
{
2222
SELINUX_DIR=$(tst_get_selinux_dir)
2323
[ "$SELINUX_DIR" ] || tst_brk TCONF "SELinux is not enabled"
24-
25-
require_ima_policy_content "$REQUIRED_POLICY" '-E' > $TST_TMPDIR/policy.txt
2624
}
2725

2826
# Format of the measured SELinux state data.
@@ -45,7 +43,7 @@ validate_policy_capabilities()
4543
measured_value=$(echo $1 | awk -F'[=;]' -v inx="$inx" '{print $inx}')
4644
expected_value=$(cat "$SELINUX_DIR/policy_capabilities/$measured_cap")
4745
if [ "$measured_value" != "$expected_value" ]; then
48-
tst_res TFAIL "$measured_cap: expected: $expected_value, got: $digest"
46+
tst_res $IMA_FAIL "$measured_cap: expected: $expected_value, got: $digest"
4947
return
5048
fi
5149

@@ -75,7 +73,7 @@ test1()
7573
# in kernel memory for SELinux
7674
line=$(grep -E "selinux-policy-hash" $ASCII_MEASUREMENTS | tail -1)
7775
if [ -z "$line" ]; then
78-
tst_res TFAIL "SELinux policy hash not measured"
76+
tst_res $IMA_FAIL "SELinux policy hash not measured"
7977
return
8078
fi
8179

@@ -86,7 +84,7 @@ test1()
8684
tst_brk TCONF "cannot compute digest for $algorithm"
8785

8886
if [ "$policy_digest" != "$expected_policy_digest" ]; then
89-
tst_res TFAIL "Digest mismatch: expected: $expected_policy_digest, got: $policy_digest"
87+
tst_res $IMA_FAIL "Digest mismatch: expected: $expected_policy_digest, got: $policy_digest"
9088
return
9189
fi
9290

@@ -116,7 +114,7 @@ test2()
116114
# state matches that currently set for SELinux
117115
line=$(grep -E "selinux-state" $ASCII_MEASUREMENTS | tail -1)
118116
if [ -z "$line" ]; then
119-
tst_res TFAIL "SELinux state not measured"
117+
tst_res $IMA_FAIL "SELinux state not measured"
120118
return
121119
fi
122120

@@ -129,7 +127,7 @@ test2()
129127
tst_brk TCONF "cannot compute digest for $algorithm"
130128

131129
if [ "$digest" != "$expected_digest" ]; then
132-
tst_res TFAIL "digest mismatch: expected: $expected_digest, got: $digest"
130+
tst_res $IMA_FAIL "digest mismatch: expected: $expected_digest, got: $digest"
133131
return
134132
fi
135133

@@ -146,20 +144,20 @@ test2()
146144
enforced_value=$(echo $measured_data | awk -F'[=;]' '{print $4}')
147145
expected_enforced_value=$(cat $SELINUX_DIR/enforce)
148146
if [ "$expected_enforced_value" != "$enforced_value" ]; then
149-
tst_res TFAIL "enforce: expected: $expected_enforced_value, got: $enforced_value"
147+
tst_res $IMA_FAIL "enforce: expected: $expected_enforced_value, got: $enforced_value"
150148
return
151149
fi
152150

153151
checkreqprot_value=$(echo $measured_data | awk -F'[=;]' '{print $6}')
154152
expected_checkreqprot_value=$(cat $SELINUX_DIR/checkreqprot)
155153
if [ "$expected_checkreqprot_value" != "$checkreqprot_value" ]; then
156-
tst_res TFAIL "checkreqprot: expected: $expected_checkreqprot_value, got: $checkreqprot_value"
154+
tst_res $IMA_FAIL "checkreqprot: expected: $expected_checkreqprot_value, got: $checkreqprot_value"
157155
return
158156
fi
159157

160158
initialized_value=$(echo $measured_data | awk -F'[=;]' '{print $2}')
161159
if [ "$initialized_value" != "1" ]; then
162-
tst_res TFAIL "initialized: expected 1, got: $initialized_value"
160+
tst_res $IMA_FAIL "initialized: expected 1, got: $initialized_value"
163161
return
164162
fi
165163

testcases/kernel/security/integrity/ima/tests/ima_setup.sh

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ SYSFS="/sys"
2020
UMOUNT=
2121
TST_FS_TYPE="ext3"
2222

23+
IMA_FAIL="TFAIL"
24+
IMA_BROK="TBROK"
25+
2326
# TODO: find support for rmd128 rmd256 rmd320 wp256 wp384 tgr128 tgr160
2427
compute_digest()
2528
{
@@ -86,21 +89,9 @@ require_policy_writable()
8689
check_ima_policy_content()
8790
{
8891
local pattern="$1"
89-
local grep_params="${2--q}"
9092

9193
check_policy_readable || return 1
92-
grep $grep_params "$pattern" $IMA_POLICY
93-
}
94-
95-
require_ima_policy_content()
96-
{
97-
local pattern="$1"
98-
local grep_params="${2--q}"
99-
100-
require_policy_readable
101-
if ! grep $grep_params "$pattern" $IMA_POLICY; then
102-
tst_brk TCONF "IMA policy does not specify '$pattern'"
103-
fi
94+
grep -q "$pattern" $IMA_POLICY
10495
}
10596

10697
check_ima_policy_cmdline()
@@ -159,6 +150,51 @@ print_ima_config()
159150
tst_res TINFO "/proc/cmdline: $(cat /proc/cmdline)"
160151
}
161152

153+
# Check for required
154+
# 1) IMA builtin policy (based on /proc/cmdline)
155+
# 2) IMA policy content (actual content of /sys/kernel/security/ima/policy)
156+
# When missing CONFIG_IMA_READ_POLICY=y on required policy convert: test, but convert TFAIL => TCONF.
157+
# $REQUIRED_POLICY_CONTENT: file with required IMA policy
158+
# $REQUIRED_BUILTIN_POLICY: IMA policy specified as kernel cmdline
159+
verify_ima_policy()
160+
{
161+
local check_content line
162+
local file="$TST_DATAROOT/$REQUIRED_POLICY_CONTENT"
163+
164+
if [ -z "$REQUIRED_POLICY_CONTENT" -a -z "$REQUIRED_BUILTIN_POLICY" ]; then
165+
return 0
166+
fi
167+
168+
if [ -n "$REQUIRED_POLICY_CONTENT" ]; then
169+
check_content=1
170+
if [ -n "$REQUIRED_BUILTIN_POLICY" ] && check_ima_policy_cmdline "$REQUIRED_BUILTIN_POLICY"; then
171+
tst_res TINFO "booted with IMA policy: $REQUIRED_BUILTIN_POLICY"
172+
return 0
173+
fi
174+
elif [ -n "$REQUIRED_BUILTIN_POLICY" ]; then
175+
require_ima_policy_cmdline "$REQUIRED_BUILTIN_POLICY"
176+
fi
177+
178+
if [ "$check_content" = 1 ]; then
179+
[ -e $file ] || tst_brk TBROK "policy file '$file' does not exist (LTPROOT=$LTPROOT)"
180+
tst_res TINFO "test requires IMA policy:"
181+
cat $file
182+
if check_policy_readable; then
183+
# check IMA policy content
184+
while read line; do
185+
if ! grep -q "$line" $IMA_POLICY; then
186+
tst_brk TCONF "missing required policy '$line'"
187+
fi
188+
IMA_POLICY_CHECKED=1
189+
done < $file
190+
else
191+
tst_res TINFO "policy is not readable, failure will be treated as TCONF"
192+
IMA_FAIL="TCONF"
193+
IMA_BROK="TCONF"
194+
fi
195+
fi
196+
}
197+
162198
ima_setup()
163199
{
164200
SECURITYFS="$(mount_helper securityfs $SYSFS/kernel/security)"
@@ -181,9 +217,7 @@ ima_setup()
181217
cd "$TST_MNTPOINT"
182218
fi
183219

184-
if [ "$REQUIRED_BUILTIN_POLICY" ]; then
185-
require_ima_policy_cmdline "$REQUIRED_BUILTIN_POLICY"
186-
fi
220+
verify_ima_policy
187221

188222
[ -n "$TST_SETUP_CALLER" ] && $TST_SETUP_CALLER
189223
}
@@ -291,7 +325,7 @@ ima_check()
291325
algorithm=$(cat tmp | cut -d'|' -f1)
292326
digest=$(cat tmp | cut -d'|' -f2)
293327
else
294-
tst_brk TBROK "failed to get algorithm/digest for '$test_file'"
328+
tst_brk $IMA_BROK "failed to get algorithm/digest for '$test_file'"
295329
fi
296330

297331
tst_res TINFO "computing digest for $algorithm algorithm"

0 commit comments

Comments
 (0)