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 if [ $ima_read_policy -eq 1 ]; then 41 check_ima_policy "appraise" "func=KEXEC_KERNEL_CHECK" \ 42 "appraise_type=imasig" 43 ret=$? 44 [ $ret -eq 1 ] && log_info "IMA signature required"; 45 fi 46 return $ret 47} 48 49# The kexec_file_load_test() is complicated enough, require pesign. 50# Return 1 for PE signature found and 0 for not found. 51check_for_pesig() 52{ 53 which pesign > /dev/null 2>&1 || log_skip "pesign not found" 54 55 pesign -i $KERNEL_IMAGE --show-signature | grep -q "No signatures" 56 local ret=$? 57 if [ $ret -eq 1 ]; then 58 log_info "kexec kernel image PE signed" 59 else 60 log_info "kexec kernel image not PE signed" 61 fi 62 return $ret 63} 64 65# The kexec_file_load_test() is complicated enough, require getfattr. 66# Return 1 for IMA signature found and 0 for not found. 67check_for_imasig() 68{ 69 local ret=0 70 71 which getfattr > /dev/null 2>&1 72 if [ $? -eq 1 ]; then 73 log_skip "getfattr not found" 74 fi 75 76 line=$(getfattr -n security.ima -e hex --absolute-names $KERNEL_IMAGE 2>&1) 77 echo $line | grep -q "security.ima=0x03" 78 if [ $? -eq 0 ]; then 79 ret=1 80 log_info "kexec kernel image IMA signed" 81 else 82 log_info "kexec kernel image not IMA signed" 83 fi 84 return $ret 85} 86 87kexec_file_load_test() 88{ 89 local succeed_msg="kexec_file_load succeeded" 90 local failed_msg="kexec_file_load failed" 91 local key_msg="try enabling the CONFIG_INTEGRITY_PLATFORM_KEYRING" 92 93 line=$(kexec --load --kexec-file-syscall $KERNEL_IMAGE 2>&1) 94 95 if [ $? -eq 0 ]; then 96 kexec --unload --kexec-file-syscall 97 98 # In secureboot mode with an architecture specific 99 # policy, make sure either an IMA or PE signature exists. 100 if [ $secureboot -eq 1 ] && [ $arch_policy -eq 1 ] && \ 101 [ $ima_signed -eq 0 ] && [ $pe_signed -eq 0 ]; then 102 log_fail "$succeed_msg (missing sig)" 103 fi 104 105 if [ $kexec_sig_required -eq 1 -o $pe_sig_required -eq 1 ] \ 106 && [ $pe_signed -eq 0 ]; then 107 log_fail "$succeed_msg (missing PE sig)" 108 fi 109 110 if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ]; then 111 log_fail "$succeed_msg (missing IMA sig)" 112 fi 113 114 if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \ 115 && [ $ima_sig_required -eq 0 ] && [ $ima_signed -eq 0 ] \ 116 && [ $ima_read_policy -eq 0 ]; then 117 log_fail "$succeed_msg (possibly missing IMA sig)" 118 fi 119 120 if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 0 ]; then 121 log_info "No signature verification required" 122 elif [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \ 123 && [ $ima_sig_required -eq 0 ] && [ $ima_signed -eq 0 ] \ 124 && [ $ima_read_policy -eq 1 ]; then 125 log_info "No signature verification required" 126 fi 127 128 log_pass "$succeed_msg" 129 fi 130 131 # Check the reason for the kexec_file_load failure 132 echo $line | grep -q "Required key not available" 133 if [ $? -eq 0 ]; then 134 if [ $platform_keyring -eq 0 ]; then 135 log_pass "$failed_msg (-ENOKEY), $key_msg" 136 else 137 log_pass "$failed_msg (-ENOKEY)" 138 fi 139 fi 140 141 if [ $kexec_sig_required -eq 1 -o $pe_sig_required -eq 1 ] \ 142 && [ $pe_signed -eq 0 ]; then 143 log_pass "$failed_msg (missing PE sig)" 144 fi 145 146 if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ]; then 147 log_pass "$failed_msg (missing IMA sig)" 148 fi 149 150 if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \ 151 && [ $ima_sig_required -eq 0 ] && [ $ima_read_policy -eq 0 ] \ 152 && [ $ima_signed -eq 0 ]; then 153 log_pass "$failed_msg (possibly missing IMA sig)" 154 fi 155 156 log_pass "$failed_msg" 157 return 0 158} 159 160# kexec requires root privileges 161require_root_privileges 162 163# get the kernel config 164get_kconfig 165 166# Determine which kernel config options are enabled 167kconfig_enabled "CONFIG_IMA_APPRAISE=y" "IMA enabled" 168ima_appraise=$? 169 170kconfig_enabled "CONFIG_IMA_ARCH_POLICY=y" \ 171 "architecture specific policy enabled" 172arch_policy=$? 173 174kconfig_enabled "CONFIG_INTEGRITY_PLATFORM_KEYRING=y" \ 175 "platform keyring enabled" 176platform_keyring=$? 177 178kconfig_enabled "CONFIG_IMA_READ_POLICY=y" "reading IMA policy permitted" 179ima_read_policy=$? 180 181kconfig_enabled "CONFIG_KEXEC_SIG_FORCE=y" \ 182 "kexec signed kernel image required" 183kexec_sig_required=$? 184 185kconfig_enabled "CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y" \ 186 "PE signed kernel image required" 187pe_sig_required=$? 188 189is_ima_sig_required 190ima_sig_required=$? 191 192get_secureboot_mode 193secureboot=$? 194 195# Are there pe and ima signatures 196check_for_pesig 197pe_signed=$? 198 199check_for_imasig 200ima_signed=$? 201 202# Test loading the kernel image via kexec_file_load syscall 203kexec_file_load_test 204