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