244 lines · bash
1#!/bin/sh2# SPDX-License-Identifier: GPL-2.03#4# Loading a kernel image via the kexec_file_load syscall can verify either5# 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 depends9# on pesign and getfattr. This test also requires the kernel to be10# built with CONFIG_IKCONFIG enabled and either CONFIG_IKCONFIG_PROC11# enabled or access to the extract-ikconfig script.12 13TEST="KEXEC_FILE_LOAD"14. ./kexec_common_lib.sh15 16trap "{ rm -f $IKCONFIG ; }" EXIT17 18# Some of the IMA builtin policies may require the kexec kernel image to19# be signed, but these policy rules may be replaced with a custom20# policy. Only CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS persists after21# loading a custom policy. Check if it is enabled, before reading the22# 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=027 28 kconfig_enabled "CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS=y" \29 "IMA kernel image signature required"30 if [ $? -eq 1 ]; then31 log_info "IMA signature required"32 return 133 fi34 35 # The architecture specific or a custom policy may require the36 # kexec kernel image be signed. Policy rules are walked37 # sequentially. As a result, a policy rule may be defined, but38 # might not necessarily be used. This test assumes if a policy39 # rule is specified, that is the intent.40 41 # First check for appended signature (modsig), then xattr42 if [ $ima_read_policy -eq 1 ]; then43 check_ima_policy "appraise" "func=KEXEC_KERNEL_CHECK" \44 "appraise_type=imasig|modsig"45 ret=$?46 if [ $ret -eq 1 ]; then47 log_info "IMA or appended(modsig) signature required"48 else49 check_ima_policy "appraise" "func=KEXEC_KERNEL_CHECK" \50 "appraise_type=imasig"51 ret=$?52 [ $ret -eq 1 ] && log_info "IMA signature required";53 fi54 fi55 return $ret56}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 ]; then67 log_info "kexec kernel image PE signed"68 else69 log_info "kexec kernel image not PE signed"70 fi71 return $ret72}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=079 80 which getfattr > /dev/null 2>&181 if [ $? -eq 1 ]; then82 log_skip "getfattr not found"83 fi84 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 ]; then88 ret=189 log_info "kexec kernel image IMA signed"90 else91 log_info "kexec kernel image not IMA signed"92 fi93 return $ret94}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=0101 102 tail --bytes $((${#module_sig_string} + 1)) $KERNEL_IMAGE | \103 grep -q "$module_sig_string"104 if [ $? -eq 0 ]; then105 ret=1106 log_info "kexec kernel image modsig signed"107 else108 log_info "kexec kernel image not modsig signed"109 fi110 return $ret111}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 ]; then122 kexec --unload --kexec-file-syscall123 124 # In secureboot mode with an architecture specific125 # 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 ]; then129 log_fail "$succeed_msg (missing sig)"130 fi131 132 if [ $kexec_sig_required -eq 1 -o $pe_sig_required -eq 1 ] \133 && [ $pe_signed -eq 0 ]; then134 log_fail "$succeed_msg (missing PE sig)"135 fi136 137 if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ] \138 && [ $ima_modsig -eq 0 ]; then139 log_fail "$succeed_msg (missing IMA sig)"140 fi141 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 ]; then145 log_fail "$succeed_msg (possibly missing IMA sig)"146 fi147 148 if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 0 ]; then149 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 ]; then153 log_info "No signature verification required"154 fi155 156 log_pass "$succeed_msg"157 fi158 159 # Check the reason for the kexec_file_load failure160 echo $line | grep -q "Required key not available"161 if [ $? -eq 0 ]; then162 if [ $platform_keyring -eq 0 ]; then163 log_pass "$failed_msg (-ENOKEY), $key_msg"164 else165 log_pass "$failed_msg (-ENOKEY)"166 fi167 fi168 169 if [ $kexec_sig_required -eq 1 -o $pe_sig_required -eq 1 ] \170 && [ $pe_signed -eq 0 ]; then171 log_pass "$failed_msg (missing PE sig)"172 fi173 174 if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ]; then175 log_pass "$failed_msg (missing IMA sig)"176 fi177 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 ]; then181 log_pass "$failed_msg (possibly missing IMA sig)"182 fi183 184 log_pass "$failed_msg"185 return 0186}187 188# kexec requires root privileges189require_root_privileges190 191# get the kernel config192get_kconfig193 194kconfig_enabled "CONFIG_KEXEC_FILE=y" "kexec_file_load is enabled"195if [ $? -eq 0 ]; then196 log_skip "kexec_file_load is not enabled"197fi198 199# Determine which kernel config options are enabled200kconfig_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_required223ima_sig_required=$?224 225get_secureboot_mode226secureboot=$?227 228# Are there pe and ima signatures229if [ "$(get_arch)" == 'ppc64le' ]; then230 pe_signed=0231else232 check_for_pesig233 pe_signed=$?234fi235 236check_for_imasig237ima_signed=$?238 239check_for_modsig240ima_modsig=$?241 242# Test loading the kernel image via kexec_file_load syscall243kexec_file_load_test244