Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/sh
0002 # SPDX-License-Identifier: GPL-2.0
0003 #
0004 # Loading a kernel image via the kexec_file_load syscall can verify either
0005 # the IMA signature stored in the security.ima xattr or the PE signature,
0006 # both signatures depending on the IMA policy, or none.
0007 #
0008 # To determine whether the kernel image is signed, this test depends
0009 # on pesign and getfattr.  This test also requires the kernel to be
0010 # built with CONFIG_IKCONFIG enabled and either CONFIG_IKCONFIG_PROC
0011 # enabled or access to the extract-ikconfig script.
0012 
0013 TEST="KEXEC_FILE_LOAD"
0014 . ./kexec_common_lib.sh
0015 
0016 trap "{ rm -f $IKCONFIG ; }" EXIT
0017 
0018 # Some of the IMA builtin policies may require the kexec kernel image to
0019 # be signed, but these policy rules may be replaced with a custom
0020 # policy.  Only CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS persists after
0021 # loading a custom policy.  Check if it is enabled, before reading the
0022 # IMA runtime sysfs policy file.
0023 # Return 1 for IMA signature required and 0 for not required.
0024 is_ima_sig_required()
0025 {
0026         local ret=0
0027 
0028         kconfig_enabled "CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS=y" \
0029                 "IMA kernel image signature required"
0030         if [ $? -eq 1 ]; then
0031                 log_info "IMA signature required"
0032                 return 1
0033         fi
0034 
0035         # The architecture specific or a custom policy may require the
0036         # kexec kernel image be signed.  Policy rules are walked
0037         # sequentially.  As a result, a policy rule may be defined, but
0038         # might not necessarily be used.  This test assumes if a policy
0039         # rule is specified, that is the intent.
0040 
0041         # First check for appended signature (modsig), then xattr
0042         if [ $ima_read_policy -eq 1 ]; then
0043                 check_ima_policy "appraise" "func=KEXEC_KERNEL_CHECK" \
0044                         "appraise_type=imasig|modsig"
0045                 ret=$?
0046                 if [ $ret -eq 1 ]; then
0047                         log_info "IMA or appended(modsig) signature required"
0048                 else
0049                         check_ima_policy "appraise" "func=KEXEC_KERNEL_CHECK" \
0050                                 "appraise_type=imasig"
0051                         ret=$?
0052                         [ $ret -eq 1 ] && log_info "IMA signature required";
0053                 fi
0054         fi
0055         return $ret
0056 }
0057 
0058 # The kexec_file_load_test() is complicated enough, require pesign.
0059 # Return 1 for PE signature found and 0 for not found.
0060 check_for_pesig()
0061 {
0062         which pesign > /dev/null 2>&1 || log_skip "pesign not found"
0063 
0064         pesign -i $KERNEL_IMAGE --show-signature | grep -q "No signatures"
0065         local ret=$?
0066         if [ $ret -eq 1 ]; then
0067                 log_info "kexec kernel image PE signed"
0068         else
0069                 log_info "kexec kernel image not PE signed"
0070         fi
0071         return $ret
0072 }
0073 
0074 # The kexec_file_load_test() is complicated enough, require getfattr.
0075 # Return 1 for IMA signature found and 0 for not found.
0076 check_for_imasig()
0077 {
0078         local ret=0
0079 
0080         which getfattr > /dev/null 2>&1
0081         if [ $? -eq 1 ]; then
0082                 log_skip "getfattr not found"
0083         fi
0084 
0085         line=$(getfattr -n security.ima -e hex --absolute-names $KERNEL_IMAGE 2>&1)
0086         echo $line | grep -q "security.ima=0x03"
0087         if [ $? -eq 0 ]; then
0088                 ret=1
0089                 log_info "kexec kernel image IMA signed"
0090         else
0091                 log_info "kexec kernel image not IMA signed"
0092         fi
0093         return $ret
0094 }
0095 
0096 # Return 1 for appended signature (modsig) found and 0 for not found.
0097 check_for_modsig()
0098 {
0099         local module_sig_string="~Module signature appended~"
0100         local ret=0
0101 
0102         tail --bytes $((${#module_sig_string} + 1)) $KERNEL_IMAGE | \
0103                 grep -q "$module_sig_string"
0104         if [ $? -eq 0 ]; then
0105                 ret=1
0106                 log_info "kexec kernel image modsig signed"
0107         else
0108                 log_info "kexec kernel image not modsig signed"
0109         fi
0110         return $ret
0111 }
0112 
0113 kexec_file_load_test()
0114 {
0115         local succeed_msg="kexec_file_load succeeded"
0116         local failed_msg="kexec_file_load failed"
0117         local key_msg="try enabling the CONFIG_INTEGRITY_PLATFORM_KEYRING"
0118 
0119         line=$(kexec --load --kexec-file-syscall $KERNEL_IMAGE 2>&1)
0120 
0121         if [ $? -eq 0 ]; then
0122                 kexec --unload --kexec-file-syscall
0123 
0124                 # In secureboot mode with an architecture  specific
0125                 # policy, make sure either an IMA or PE signature exists.
0126                 if [ $secureboot -eq 1 ] && [ $arch_policy -eq 1 ] && \
0127                         [ $ima_signed -eq 0 ] && [ $pe_signed -eq 0 ] \
0128                           && [ $ima_modsig -eq 0 ]; then
0129                         log_fail "$succeed_msg (missing sig)"
0130                 fi
0131 
0132                 if [ $kexec_sig_required -eq 1 -o $pe_sig_required -eq 1 ] \
0133                      && [ $pe_signed -eq 0 ]; then
0134                         log_fail "$succeed_msg (missing PE sig)"
0135                 fi
0136 
0137                 if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ] \
0138                      && [ $ima_modsig -eq 0 ]; then
0139                         log_fail "$succeed_msg (missing IMA sig)"
0140                 fi
0141 
0142                 if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \
0143                     && [ $ima_sig_required -eq 0 ] && [ $ima_signed -eq 0 ] \
0144                     && [ $ima_read_policy -eq 0 ]; then
0145                         log_fail "$succeed_msg (possibly missing IMA sig)"
0146                 fi
0147 
0148                 if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 0 ]; then
0149                         log_info "No signature verification required"
0150                 elif [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \
0151                     && [ $ima_sig_required -eq 0 ] && [ $ima_signed -eq 0 ] \
0152                     && [ $ima_read_policy -eq 1 ]; then
0153                         log_info "No signature verification required"
0154                 fi
0155 
0156                 log_pass "$succeed_msg"
0157         fi
0158 
0159         # Check the reason for the kexec_file_load failure
0160         echo $line | grep -q "Required key not available"
0161         if [ $? -eq 0 ]; then
0162                 if [ $platform_keyring -eq 0 ]; then
0163                         log_pass "$failed_msg (-ENOKEY), $key_msg"
0164                 else
0165                         log_pass "$failed_msg (-ENOKEY)"
0166                 fi
0167         fi
0168 
0169         if [ $kexec_sig_required -eq 1 -o $pe_sig_required -eq 1 ] \
0170              && [ $pe_signed -eq 0 ]; then
0171                 log_pass "$failed_msg (missing PE sig)"
0172         fi
0173 
0174         if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ]; then
0175                 log_pass "$failed_msg (missing IMA sig)"
0176         fi
0177 
0178         if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \
0179             && [ $ima_sig_required -eq 0 ] && [ $ima_read_policy -eq 0 ] \
0180             && [ $ima_signed -eq 0 ]; then
0181                 log_pass "$failed_msg (possibly missing IMA sig)"
0182         fi
0183 
0184         log_pass "$failed_msg"
0185         return 0
0186 }
0187 
0188 # kexec requires root privileges
0189 require_root_privileges
0190 
0191 # get the kernel config
0192 get_kconfig
0193 
0194 kconfig_enabled "CONFIG_KEXEC_FILE=y" "kexec_file_load is enabled"
0195 if [ $? -eq 0 ]; then
0196         log_skip "kexec_file_load is not enabled"
0197 fi
0198 
0199 # Determine which kernel config options are enabled
0200 kconfig_enabled "CONFIG_IMA_APPRAISE=y" "IMA enabled"
0201 ima_appraise=$?
0202 
0203 kconfig_enabled "CONFIG_IMA_ARCH_POLICY=y" \
0204         "architecture specific policy enabled"
0205 arch_policy=$?
0206 
0207 kconfig_enabled "CONFIG_INTEGRITY_PLATFORM_KEYRING=y" \
0208         "platform keyring enabled"
0209 platform_keyring=$?
0210 
0211 kconfig_enabled "CONFIG_IMA_READ_POLICY=y" "reading IMA policy permitted"
0212 ima_read_policy=$?
0213 
0214 kconfig_enabled "CONFIG_KEXEC_SIG_FORCE=y" \
0215         "kexec signed kernel image required"
0216 kexec_sig_required=$?
0217 
0218 kconfig_enabled "CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y" \
0219         "PE signed kernel image required"
0220 pe_sig_required=$?
0221 
0222 is_ima_sig_required
0223 ima_sig_required=$?
0224 
0225 get_secureboot_mode
0226 secureboot=$?
0227 
0228 # Are there pe and ima signatures
0229 if [ "$(get_arch)" == 'ppc64le' ]; then
0230         pe_signed=0
0231 else
0232         check_for_pesig
0233         pe_signed=$?
0234 fi
0235 
0236 check_for_imasig
0237 ima_signed=$?
0238 
0239 check_for_modsig
0240 ima_modsig=$?
0241 
0242 # Test loading the kernel image via kexec_file_load syscall
0243 kexec_file_load_test