1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0 3# 4# Loading a kernel image via the kexec_file_load syscall can verify either 5# the IMA signature stored in the security.ima xattr or the PE signature, 6# both signatures depending on the IMA policy, or none. 7# 8# To determine whether the kernel image is signed, this test depends 9# on pesign and getfattr. This test also requires the kernel to be 10# built with CONFIG_IKCONFIG enabled and either CONFIG_IKCONFIG_PROC 11# enabled or access to the extract-ikconfig script. 12 13TEST="KEXEC_FILE_LOAD" 14. ./kexec_common_lib.sh 15 16trap "{ rm -f $IKCONFIG ; }" EXIT 17 18# Some of the IMA builtin policies may require the kexec kernel image to 19# be signed, but these policy rules may be replaced with a custom 20# policy. Only CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS persists after 21# loading a custom policy. Check if it is enabled, before reading the 22# IMA runtime sysfs policy file. 23# Return 1 for IMA signature required and 0 for not required. 24is_ima_sig_required() 25{ 26 local ret=0 27 28 kconfig_enabled "CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS=y" \ 29 "IMA kernel image signature required" 30 if [ $? -eq 1 ]; then 31 log_info "IMA signature required" 32 return 1 33 fi 34 35 # The architecture specific or a custom policy may require the 36 # kexec kernel image be signed. Policy rules are walked 37 # sequentially. As a result, a policy rule may be defined, but 38 # might not necessarily be used. This test assumes if a policy 39 # rule is specified, that is the intent. 40 41 # First check for appended signature (modsig), then xattr 42 if [ $ima_read_policy -eq 1 ]; then 43 check_ima_policy "appraise" "func=KEXEC_KERNEL_CHECK" \ 44 "appraise_type=imasig|modsig" 45 ret=$? 46 if [ $ret -eq 1 ]; then 47 log_info "IMA or appended(modsig) signature required" 48 else 49 check_ima_policy "appraise" "func=KEXEC_KERNEL_CHECK" \ 50 "appraise_type=imasig" 51 ret=$? 52 [ $ret -eq 1 ] && log_info "IMA signature required"; 53 fi 54 fi 55 return $ret 56} 57 58# The kexec_file_load_test() is complicated enough, require pesign. 59# Return 1 for PE signature found and 0 for not found. 60check_for_pesig() 61{ 62 which pesign > /dev/null 2>&1 || log_skip "pesign not found" 63 64 pesign -i $KERNEL_IMAGE --show-signature | grep -q "No signatures" 65 local ret=$? 66 if [ $ret -eq 1 ]; then 67 log_info "kexec kernel image PE signed" 68 else 69 log_info "kexec kernel image not PE signed" 70 fi 71 return $ret 72} 73 74# The kexec_file_load_test() is complicated enough, require getfattr. 75# Return 1 for IMA signature found and 0 for not found. 76check_for_imasig() 77{ 78 local ret=0 79 80 which getfattr > /dev/null 2>&1 81 if [ $? -eq 1 ]; then 82 log_skip "getfattr not found" 83 fi 84 85 line=$(getfattr -n security.ima -e hex --absolute-names $KERNEL_IMAGE 2>&1) 86 echo $line | grep -q "security.ima=0x03" 87 if [ $? -eq 0 ]; then 88 ret=1 89 log_info "kexec kernel image IMA signed" 90 else 91 log_info "kexec kernel image not IMA signed" 92 fi 93 return $ret 94} 95 96# Return 1 for appended signature (modsig) found and 0 for not found. 97check_for_modsig() 98{ 99 local module_sig_string="~Module signature appended~" 100 local sig="$(tail --bytes $((${#module_sig_string} + 1)) $KERNEL_IMAGE)" 101 local ret=0 102 103 if [ "$sig" == "$module_sig_string" ]; then 104 ret=1 105 log_info "kexec kernel image modsig signed" 106 else 107 log_info "kexec kernel image not modsig signed" 108 fi 109 return $ret 110} 111 112kexec_file_load_test() 113{ 114 local succeed_msg="kexec_file_load succeeded" 115 local failed_msg="kexec_file_load failed" 116 local key_msg="try enabling the CONFIG_INTEGRITY_PLATFORM_KEYRING" 117 118 line=$(kexec --load --kexec-file-syscall $KERNEL_IMAGE 2>&1) 119 120 if [ $? -eq 0 ]; then 121 kexec --unload --kexec-file-syscall 122 123 # In secureboot mode with an architecture specific 124 # policy, make sure either an IMA or PE signature exists. 125 if [ $secureboot -eq 1 ] && [ $arch_policy -eq 1 ] && \ 126 [ $ima_signed -eq 0 ] && [ $pe_signed -eq 0 ] \ 127 && [ $ima_modsig -eq 0 ]; then 128 log_fail "$succeed_msg (missing sig)" 129 fi 130 131 if [ $kexec_sig_required -eq 1 -o $pe_sig_required -eq 1 ] \ 132 && [ $pe_signed -eq 0 ]; then 133 log_fail "$succeed_msg (missing PE sig)" 134 fi 135 136 if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ] \ 137 && [ $ima_modsig -eq 0 ]; then 138 log_fail "$succeed_msg (missing IMA sig)" 139 fi 140 141 if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \ 142 && [ $ima_sig_required -eq 0 ] && [ $ima_signed -eq 0 ] \ 143 && [ $ima_read_policy -eq 0 ]; then 144 log_fail "$succeed_msg (possibly missing IMA sig)" 145 fi 146 147 if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 0 ]; then 148 log_info "No signature verification required" 149 elif [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \ 150 && [ $ima_sig_required -eq 0 ] && [ $ima_signed -eq 0 ] \ 151 && [ $ima_read_policy -eq 1 ]; then 152 log_info "No signature verification required" 153 fi 154 155 log_pass "$succeed_msg" 156 fi 157 158 # Check the reason for the kexec_file_load failure 159 echo $line | grep -q "Required key not available" 160 if [ $? -eq 0 ]; then 161 if [ $platform_keyring -eq 0 ]; then 162 log_pass "$failed_msg (-ENOKEY), $key_msg" 163 else 164 log_pass "$failed_msg (-ENOKEY)" 165 fi 166 fi 167 168 if [ $kexec_sig_required -eq 1 -o $pe_sig_required -eq 1 ] \ 169 && [ $pe_signed -eq 0 ]; then 170 log_pass "$failed_msg (missing PE sig)" 171 fi 172 173 if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ]; then 174 log_pass "$failed_msg (missing IMA sig)" 175 fi 176 177 if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \ 178 && [ $ima_sig_required -eq 0 ] && [ $ima_read_policy -eq 0 ] \ 179 && [ $ima_signed -eq 0 ]; then 180 log_pass "$failed_msg (possibly missing IMA sig)" 181 fi 182 183 log_pass "$failed_msg" 184 return 0 185} 186 187# kexec requires root privileges 188require_root_privileges 189 190# get the kernel config 191get_kconfig 192 193kconfig_enabled "CONFIG_KEXEC_FILE=y" "kexec_file_load is enabled" 194if [ $? -eq 0 ]; then 195 log_skip "kexec_file_load is not enabled" 196fi 197 198# Determine which kernel config options are enabled 199kconfig_enabled "CONFIG_IMA_APPRAISE=y" "IMA enabled" 200ima_appraise=$? 201 202kconfig_enabled "CONFIG_IMA_ARCH_POLICY=y" \ 203 "architecture specific policy enabled" 204arch_policy=$? 205 206kconfig_enabled "CONFIG_INTEGRITY_PLATFORM_KEYRING=y" \ 207 "platform keyring enabled" 208platform_keyring=$? 209 210kconfig_enabled "CONFIG_IMA_READ_POLICY=y" "reading IMA policy permitted" 211ima_read_policy=$? 212 213kconfig_enabled "CONFIG_KEXEC_SIG_FORCE=y" \ 214 "kexec signed kernel image required" 215kexec_sig_required=$? 216 217kconfig_enabled "CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y" \ 218 "PE signed kernel image required" 219pe_sig_required=$? 220 221is_ima_sig_required 222ima_sig_required=$? 223 224get_secureboot_mode 225secureboot=$? 226 227# Are there pe and ima signatures 228check_for_pesig 229pe_signed=$? 230 231check_for_imasig 232ima_signed=$? 233 234check_for_modsig 235ima_modsig=$? 236 237# Test loading the kernel image via kexec_file_load syscall 238kexec_file_load_test 239