test_kexec_file_load.sh (6817B)
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 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 113kexec_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 189require_root_privileges 190 191# get the kernel config 192get_kconfig 193 194kconfig_enabled "CONFIG_KEXEC_FILE=y" "kexec_file_load is enabled" 195if [ $? -eq 0 ]; then 196 log_skip "kexec_file_load is not enabled" 197fi 198 199# Determine which kernel config options are enabled 200kconfig_enabled "CONFIG_IMA_APPRAISE=y" "IMA enabled" 201ima_appraise=$? 202 203kconfig_enabled "CONFIG_IMA_ARCH_POLICY=y" \ 204 "architecture specific policy enabled" 205arch_policy=$? 206 207kconfig_enabled "CONFIG_INTEGRITY_PLATFORM_KEYRING=y" \ 208 "platform keyring enabled" 209platform_keyring=$? 210 211kconfig_enabled "CONFIG_IMA_READ_POLICY=y" "reading IMA policy permitted" 212ima_read_policy=$? 213 214kconfig_enabled "CONFIG_KEXEC_SIG_FORCE=y" \ 215 "kexec signed kernel image required" 216kexec_sig_required=$? 217 218kconfig_enabled "CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y" \ 219 "PE signed kernel image required" 220pe_sig_required=$? 221 222is_ima_sig_required 223ima_sig_required=$? 224 225get_secureboot_mode 226secureboot=$? 227 228# Are there pe and ima signatures 229if [ "$(get_arch)" == 'ppc64le' ]; then 230 pe_signed=0 231else 232 check_for_pesig 233 pe_signed=$? 234fi 235 236check_for_imasig 237ima_signed=$? 238 239check_for_modsig 240ima_modsig=$? 241 242# Test loading the kernel image via kexec_file_load syscall 243kexec_file_load_test