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 13 TEST="KEXEC_FILE_LOAD" 14 . ./kexec_common_lib.sh 15 16 trap "{ 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. 24 is_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. 60 check_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. 76 check_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. 97 check_for_modsig() 98 { 99 local module_sig_string="~Module signature appended~" 100 local ret=0 101 102 tail --bytes $((${#module_sig_string} + 1)) $KERNEL_IMAGE | \ 103 grep -q "$module_sig_string" 104 if [ $? -eq 0 ]; then 105 ret=1 106 log_info "kexec kernel image modsig signed" 107 else 108 log_info "kexec kernel image not modsig signed" 109 fi 110 return $ret 111 } 112 113 kexec_file_load_test() 114 { 115 local succeed_msg="kexec_file_load succeeded" 116 local failed_msg="kexec_file_load failed" 117 local key_msg="try enabling the CONFIG_INTEGRITY_PLATFORM_KEYRING" 118 119 line=$(kexec --load --kexec-file-syscall $KERNEL_IMAGE 2>&1) 120 121 if [ $? -eq 0 ]; then 122 kexec --unload --kexec-file-syscall 123 124 # In secureboot mode with an architecture specific 125 # policy, make sure either an IMA or PE signature exists. 126 if [ $secureboot -eq 1 ] && [ $arch_policy -eq 1 ] && \ 127 [ $ima_signed -eq 0 ] && [ $pe_signed -eq 0 ] \ 128 && [ $ima_modsig -eq 0 ]; then 129 log_fail "$succeed_msg (missing sig)" 130 fi 131 132 if [ $kexec_sig_required -eq 1 -o $pe_sig_required -eq 1 ] \ 133 && [ $pe_signed -eq 0 ]; then 134 log_fail "$succeed_msg (missing PE sig)" 135 fi 136 137 if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ] \ 138 && [ $ima_modsig -eq 0 ]; then 139 log_fail "$succeed_msg (missing IMA sig)" 140 fi 141 142 if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \ 143 && [ $ima_sig_required -eq 0 ] && [ $ima_signed -eq 0 ] \ 144 && [ $ima_read_policy -eq 0 ]; then 145 log_fail "$succeed_msg (possibly missing IMA sig)" 146 fi 147 148 if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 0 ]; then 149 log_info "No signature verification required" 150 elif [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \ 151 && [ $ima_sig_required -eq 0 ] && [ $ima_signed -eq 0 ] \ 152 && [ $ima_read_policy -eq 1 ]; then 153 log_info "No signature verification required" 154 fi 155 156 log_pass "$succeed_msg" 157 fi 158 159 # Check the reason for the kexec_file_load failure 160 echo $line | grep -q "Required key not available" 161 if [ $? -eq 0 ]; then 162 if [ $platform_keyring -eq 0 ]; then 163 log_pass "$failed_msg (-ENOKEY), $key_msg" 164 else 165 log_pass "$failed_msg (-ENOKEY)" 166 fi 167 fi 168 169 if [ $kexec_sig_required -eq 1 -o $pe_sig_required -eq 1 ] \ 170 && [ $pe_signed -eq 0 ]; then 171 log_pass "$failed_msg (missing PE sig)" 172 fi 173 174 if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ]; then 175 log_pass "$failed_msg (missing IMA sig)" 176 fi 177 178 if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \ 179 && [ $ima_sig_required -eq 0 ] && [ $ima_read_policy -eq 0 ] \ 180 && [ $ima_signed -eq 0 ]; then 181 log_pass "$failed_msg (possibly missing IMA sig)" 182 fi 183 184 log_pass "$failed_msg" 185 return 0 186 } 187 188 # kexec requires root privileges 189 require_root_privileges 190 191 # get the kernel config 192 get_kconfig 193 194 kconfig_enabled "CONFIG_KEXEC_FILE=y" "kexec_file_load is enabled" 195 if [ $? -eq 0 ]; then 196 log_skip "kexec_file_load is not enabled" 197 fi 198 199 # Determine which kernel config options are enabled 200 kconfig_enabled "CONFIG_IMA_APPRAISE=y" "IMA enabled" 201 ima_appraise=$? 202 203 kconfig_enabled "CONFIG_IMA_ARCH_POLICY=y" \ 204 "architecture specific policy enabled" 205 arch_policy=$? 206 207 kconfig_enabled "CONFIG_INTEGRITY_PLATFORM_KEYRING=y" \ 208 "platform keyring enabled" 209 platform_keyring=$? 210 211 kconfig_enabled "CONFIG_IMA_READ_POLICY=y" "reading IMA policy permitted" 212 ima_read_policy=$? 213 214 kconfig_enabled "CONFIG_KEXEC_SIG_FORCE=y" \ 215 "kexec signed kernel image required" 216 kexec_sig_required=$? 217 218 kconfig_enabled "CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y" \ 219 "PE signed kernel image required" 220 pe_sig_required=$? 221 222 is_ima_sig_required 223 ima_sig_required=$? 224 225 get_secureboot_mode 226 secureboot=$? 227 228 # Are there pe and ima signatures 229 if [ "$(get_arch)" == 'ppc64le' ]; then 230 pe_signed=0 231 else 232 check_for_pesig 233 pe_signed=$? 234 fi 235 236 check_for_imasig 237 ima_signed=$? 238 239 check_for_modsig 240 ima_modsig=$? 241 242 # Test loading the kernel image via kexec_file_load syscall 243 kexec_file_load_test
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.