1973b71c6SMimi Zohar#!/bin/sh
2973b71c6SMimi Zohar# SPDX-License-Identifier: GPL-2.0
3973b71c6SMimi Zohar#
4973b71c6SMimi Zohar# Loading a kernel image via the kexec_file_load syscall can verify either
5973b71c6SMimi Zohar# the IMA signature stored in the security.ima xattr or the PE signature,
6973b71c6SMimi Zohar# both signatures depending on the IMA policy, or none.
7973b71c6SMimi Zohar#
8973b71c6SMimi Zohar# To determine whether the kernel image is signed, this test depends
9973b71c6SMimi Zohar# on pesign and getfattr.  This test also requires the kernel to be
10973b71c6SMimi Zohar# built with CONFIG_IKCONFIG enabled and either CONFIG_IKCONFIG_PROC
11973b71c6SMimi Zohar# enabled or access to the extract-ikconfig script.
12973b71c6SMimi Zohar
13973b71c6SMimi ZoharTEST="KEXEC_FILE_LOAD"
14973b71c6SMimi Zohar. ./kexec_common_lib.sh
15973b71c6SMimi Zohar
16973b71c6SMimi Zohartrap "{ rm -f $IKCONFIG ; }" EXIT
17973b71c6SMimi Zohar
18973b71c6SMimi Zohar# Some of the IMA builtin policies may require the kexec kernel image to
19973b71c6SMimi Zohar# be signed, but these policy rules may be replaced with a custom
20973b71c6SMimi Zohar# policy.  Only CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS persists after
21973b71c6SMimi Zohar# loading a custom policy.  Check if it is enabled, before reading the
22973b71c6SMimi Zohar# IMA runtime sysfs policy file.
23973b71c6SMimi Zohar# Return 1 for IMA signature required and 0 for not required.
24973b71c6SMimi Zoharis_ima_sig_required()
25973b71c6SMimi Zohar{
26973b71c6SMimi Zohar	local ret=0
27973b71c6SMimi Zohar
28973b71c6SMimi Zohar	kconfig_enabled "CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS=y" \
29973b71c6SMimi Zohar		"IMA kernel image signature required"
30973b71c6SMimi Zohar	if [ $? -eq 1 ]; then
31973b71c6SMimi Zohar		log_info "IMA signature required"
32973b71c6SMimi Zohar		return 1
33973b71c6SMimi Zohar	fi
34973b71c6SMimi Zohar
35973b71c6SMimi Zohar	# The architecture specific or a custom policy may require the
36973b71c6SMimi Zohar	# kexec kernel image be signed.  Policy rules are walked
37973b71c6SMimi Zohar	# sequentially.  As a result, a policy rule may be defined, but
38973b71c6SMimi Zohar	# might not necessarily be used.  This test assumes if a policy
39973b71c6SMimi Zohar	# rule is specified, that is the intent.
40cbc0425dSMimi Zohar
41cbc0425dSMimi Zohar	# First check for appended signature (modsig), then xattr
42973b71c6SMimi Zohar	if [ $ima_read_policy -eq 1 ]; then
43973b71c6SMimi Zohar		check_ima_policy "appraise" "func=KEXEC_KERNEL_CHECK" \
44cbc0425dSMimi Zohar			"appraise_type=imasig|modsig"
45cbc0425dSMimi Zohar		ret=$?
46cbc0425dSMimi Zohar		if [ $ret -eq 1 ]; then
47cbc0425dSMimi Zohar			log_info "IMA or appended(modsig) signature required"
48cbc0425dSMimi Zohar		else
49cbc0425dSMimi Zohar			check_ima_policy "appraise" "func=KEXEC_KERNEL_CHECK" \
50973b71c6SMimi Zohar				"appraise_type=imasig"
51973b71c6SMimi Zohar			ret=$?
52973b71c6SMimi Zohar			[ $ret -eq 1 ] && log_info "IMA signature required";
53973b71c6SMimi Zohar		fi
54cbc0425dSMimi Zohar	fi
55973b71c6SMimi Zohar	return $ret
56973b71c6SMimi Zohar}
57973b71c6SMimi Zohar
58973b71c6SMimi Zohar# The kexec_file_load_test() is complicated enough, require pesign.
59973b71c6SMimi Zohar# Return 1 for PE signature found and 0 for not found.
60973b71c6SMimi Zoharcheck_for_pesig()
61973b71c6SMimi Zohar{
62973b71c6SMimi Zohar	which pesign > /dev/null 2>&1 || log_skip "pesign not found"
63973b71c6SMimi Zohar
64973b71c6SMimi Zohar	pesign -i $KERNEL_IMAGE --show-signature | grep -q "No signatures"
65973b71c6SMimi Zohar	local ret=$?
66973b71c6SMimi Zohar	if [ $ret -eq 1 ]; then
67973b71c6SMimi Zohar		log_info "kexec kernel image PE signed"
68973b71c6SMimi Zohar	else
69973b71c6SMimi Zohar		log_info "kexec kernel image not PE signed"
70973b71c6SMimi Zohar	fi
71973b71c6SMimi Zohar	return $ret
72973b71c6SMimi Zohar}
73973b71c6SMimi Zohar
74973b71c6SMimi Zohar# The kexec_file_load_test() is complicated enough, require getfattr.
75973b71c6SMimi Zohar# Return 1 for IMA signature found and 0 for not found.
76973b71c6SMimi Zoharcheck_for_imasig()
77973b71c6SMimi Zohar{
78973b71c6SMimi Zohar	local ret=0
79973b71c6SMimi Zohar
80973b71c6SMimi Zohar	which getfattr > /dev/null 2>&1
81973b71c6SMimi Zohar	if [ $?	-eq 1 ]; then
82973b71c6SMimi Zohar		log_skip "getfattr not found"
83973b71c6SMimi Zohar	fi
84973b71c6SMimi Zohar
85973b71c6SMimi Zohar	line=$(getfattr -n security.ima -e hex --absolute-names $KERNEL_IMAGE 2>&1)
86973b71c6SMimi Zohar	echo $line | grep -q "security.ima=0x03"
87973b71c6SMimi Zohar	if [ $? -eq 0 ]; then
88973b71c6SMimi Zohar		ret=1
89973b71c6SMimi Zohar		log_info "kexec kernel image IMA signed"
90973b71c6SMimi Zohar	else
91973b71c6SMimi Zohar		log_info "kexec kernel image not IMA signed"
92973b71c6SMimi Zohar	fi
93973b71c6SMimi Zohar	return $ret
94973b71c6SMimi Zohar}
95973b71c6SMimi Zohar
96cbc0425dSMimi Zohar# Return 1 for appended signature (modsig) found and 0 for not found.
97cbc0425dSMimi Zoharcheck_for_modsig()
98cbc0425dSMimi Zohar{
99cbc0425dSMimi Zohar	local module_sig_string="~Module signature appended~"
100cbc0425dSMimi Zohar	local ret=0
101cbc0425dSMimi Zohar
102cef5cd25SMimi Zohar	tail --bytes $((${#module_sig_string} + 1)) $KERNEL_IMAGE | \
103cef5cd25SMimi Zohar		grep -q "$module_sig_string"
104cef5cd25SMimi Zohar	if [ $? -eq 0 ]; then
105cbc0425dSMimi Zohar		ret=1
106cbc0425dSMimi Zohar		log_info "kexec kernel image modsig signed"
107cbc0425dSMimi Zohar	else
108cbc0425dSMimi Zohar		log_info "kexec kernel image not modsig signed"
109cbc0425dSMimi Zohar	fi
110cbc0425dSMimi Zohar	return $ret
111cbc0425dSMimi Zohar}
112cbc0425dSMimi Zohar
113973b71c6SMimi Zoharkexec_file_load_test()
114973b71c6SMimi Zohar{
115973b71c6SMimi Zohar	local succeed_msg="kexec_file_load succeeded"
116973b71c6SMimi Zohar	local failed_msg="kexec_file_load failed"
117973b71c6SMimi Zohar	local key_msg="try enabling the CONFIG_INTEGRITY_PLATFORM_KEYRING"
118973b71c6SMimi Zohar
119973b71c6SMimi Zohar	line=$(kexec --load --kexec-file-syscall $KERNEL_IMAGE 2>&1)
120973b71c6SMimi Zohar
121973b71c6SMimi Zohar	if [ $? -eq 0 ]; then
122973b71c6SMimi Zohar		kexec --unload --kexec-file-syscall
123973b71c6SMimi Zohar
124973b71c6SMimi Zohar		# In secureboot mode with an architecture  specific
125973b71c6SMimi Zohar		# policy, make sure either an IMA or PE signature exists.
126973b71c6SMimi Zohar		if [ $secureboot -eq 1 ] && [ $arch_policy -eq 1 ] && \
127cbc0425dSMimi Zohar			[ $ima_signed -eq 0 ] && [ $pe_signed -eq 0 ] \
128cbc0425dSMimi Zohar			  && [ $ima_modsig -eq 0 ]; then
129973b71c6SMimi Zohar			log_fail "$succeed_msg (missing sig)"
130973b71c6SMimi Zohar		fi
131973b71c6SMimi Zohar
132973b71c6SMimi Zohar		if [ $kexec_sig_required -eq 1 -o $pe_sig_required -eq 1 ] \
133973b71c6SMimi Zohar		     && [ $pe_signed -eq 0 ]; then
134973b71c6SMimi Zohar			log_fail "$succeed_msg (missing PE sig)"
135973b71c6SMimi Zohar		fi
136973b71c6SMimi Zohar
137cbc0425dSMimi Zohar		if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ] \
138cbc0425dSMimi Zohar		     && [ $ima_modsig -eq 0 ]; then
139973b71c6SMimi Zohar			log_fail "$succeed_msg (missing IMA sig)"
140973b71c6SMimi Zohar		fi
141973b71c6SMimi Zohar
142973b71c6SMimi Zohar		if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \
143973b71c6SMimi Zohar		    && [ $ima_sig_required -eq 0 ] && [ $ima_signed -eq 0 ] \
144973b71c6SMimi Zohar	            && [ $ima_read_policy -eq 0 ]; then
145973b71c6SMimi Zohar			log_fail "$succeed_msg (possibly missing IMA sig)"
146973b71c6SMimi Zohar		fi
147973b71c6SMimi Zohar
148973b71c6SMimi Zohar		if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 0 ]; then
149973b71c6SMimi Zohar			log_info "No signature verification required"
150973b71c6SMimi Zohar		elif [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \
151973b71c6SMimi Zohar		    && [ $ima_sig_required -eq 0 ] && [ $ima_signed -eq 0 ] \
152973b71c6SMimi Zohar	            && [ $ima_read_policy -eq 1 ]; then
153973b71c6SMimi Zohar			log_info "No signature verification required"
154973b71c6SMimi Zohar		fi
155973b71c6SMimi Zohar
156973b71c6SMimi Zohar		log_pass "$succeed_msg"
157973b71c6SMimi Zohar	fi
158973b71c6SMimi Zohar
159973b71c6SMimi Zohar	# Check the reason for the kexec_file_load failure
160973b71c6SMimi Zohar	echo $line | grep -q "Required key not available"
161973b71c6SMimi Zohar	if [ $? -eq 0 ]; then
162973b71c6SMimi Zohar		if [ $platform_keyring -eq 0 ]; then
163973b71c6SMimi Zohar			log_pass "$failed_msg (-ENOKEY), $key_msg"
164973b71c6SMimi Zohar		else
165973b71c6SMimi Zohar			log_pass "$failed_msg (-ENOKEY)"
166973b71c6SMimi Zohar		fi
167973b71c6SMimi Zohar	fi
168973b71c6SMimi Zohar
169973b71c6SMimi Zohar	if [ $kexec_sig_required -eq 1 -o $pe_sig_required -eq 1 ] \
170973b71c6SMimi Zohar	     && [ $pe_signed -eq 0 ]; then
171973b71c6SMimi Zohar		log_pass "$failed_msg (missing PE sig)"
172973b71c6SMimi Zohar	fi
173973b71c6SMimi Zohar
174973b71c6SMimi Zohar	if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ]; then
175973b71c6SMimi Zohar		log_pass "$failed_msg (missing IMA sig)"
176973b71c6SMimi Zohar	fi
177973b71c6SMimi Zohar
178973b71c6SMimi Zohar	if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \
179973b71c6SMimi Zohar	    && [ $ima_sig_required -eq 0 ] && [ $ima_read_policy -eq 0 ] \
180973b71c6SMimi Zohar	    && [ $ima_signed -eq 0 ]; then
181973b71c6SMimi Zohar		log_pass "$failed_msg (possibly missing IMA sig)"
182973b71c6SMimi Zohar	fi
183973b71c6SMimi Zohar
184973b71c6SMimi Zohar	log_pass "$failed_msg"
185973b71c6SMimi Zohar	return 0
186973b71c6SMimi Zohar}
187973b71c6SMimi Zohar
188973b71c6SMimi Zohar# kexec requires root privileges
189973b71c6SMimi Zoharrequire_root_privileges
190973b71c6SMimi Zohar
191973b71c6SMimi Zohar# get the kernel config
192973b71c6SMimi Zoharget_kconfig
193973b71c6SMimi Zohar
1947cea0b92SMimi Zoharkconfig_enabled "CONFIG_KEXEC_FILE=y" "kexec_file_load is enabled"
1957cea0b92SMimi Zoharif [ $? -eq 0 ]; then
1967cea0b92SMimi Zohar	log_skip "kexec_file_load is not enabled"
1977cea0b92SMimi Zoharfi
1987cea0b92SMimi Zohar
199973b71c6SMimi Zohar# Determine which kernel config options are enabled
200973b71c6SMimi Zoharkconfig_enabled "CONFIG_IMA_APPRAISE=y" "IMA enabled"
201973b71c6SMimi Zoharima_appraise=$?
202973b71c6SMimi Zohar
203973b71c6SMimi Zoharkconfig_enabled "CONFIG_IMA_ARCH_POLICY=y" \
204973b71c6SMimi Zohar	"architecture specific policy enabled"
205973b71c6SMimi Zohararch_policy=$?
206973b71c6SMimi Zohar
207973b71c6SMimi Zoharkconfig_enabled "CONFIG_INTEGRITY_PLATFORM_KEYRING=y" \
208973b71c6SMimi Zohar	"platform keyring enabled"
209973b71c6SMimi Zoharplatform_keyring=$?
210973b71c6SMimi Zohar
211973b71c6SMimi Zoharkconfig_enabled "CONFIG_IMA_READ_POLICY=y" "reading IMA policy permitted"
212973b71c6SMimi Zoharima_read_policy=$?
213973b71c6SMimi Zohar
214973b71c6SMimi Zoharkconfig_enabled "CONFIG_KEXEC_SIG_FORCE=y" \
215973b71c6SMimi Zohar	"kexec signed kernel image required"
216973b71c6SMimi Zoharkexec_sig_required=$?
217973b71c6SMimi Zohar
218973b71c6SMimi Zoharkconfig_enabled "CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y" \
219973b71c6SMimi Zohar	"PE signed kernel image required"
220973b71c6SMimi Zoharpe_sig_required=$?
221973b71c6SMimi Zohar
222973b71c6SMimi Zoharis_ima_sig_required
223973b71c6SMimi Zoharima_sig_required=$?
224973b71c6SMimi Zohar
225973b71c6SMimi Zoharget_secureboot_mode
226973b71c6SMimi Zoharsecureboot=$?
227973b71c6SMimi Zohar
228973b71c6SMimi Zohar# Are there pe and ima signatures
229*65e38e32SNageswara R Sastryif [ "$(get_arch)" == 'ppc64le' ]; then
230*65e38e32SNageswara R Sastry	pe_signed=0
231*65e38e32SNageswara R Sastryelse
232973b71c6SMimi Zohar	check_for_pesig
233973b71c6SMimi Zohar	pe_signed=$?
234*65e38e32SNageswara R Sastryfi
235973b71c6SMimi Zohar
236973b71c6SMimi Zoharcheck_for_imasig
237973b71c6SMimi Zoharima_signed=$?
238973b71c6SMimi Zohar
239cbc0425dSMimi Zoharcheck_for_modsig
240cbc0425dSMimi Zoharima_modsig=$?
241cbc0425dSMimi Zohar
242973b71c6SMimi Zohar# Test loading the kernel image via kexec_file_load syscall
243973b71c6SMimi Zoharkexec_file_load_test
244