test_kexec_file_load.sh 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  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. TEST="KEXEC_FILE_LOAD"
  13. . ./kexec_common_lib.sh
  14. trap "{ rm -f $IKCONFIG ; }" EXIT
  15. # Some of the IMA builtin policies may require the kexec kernel image to
  16. # be signed, but these policy rules may be replaced with a custom
  17. # policy. Only CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS persists after
  18. # loading a custom policy. Check if it is enabled, before reading the
  19. # IMA runtime sysfs policy file.
  20. # Return 1 for IMA signature required and 0 for not required.
  21. is_ima_sig_required()
  22. {
  23. local ret=0
  24. kconfig_enabled "CONFIG_IMA_APPRAISE_REQUIRE_KEXEC_SIGS=y" \
  25. "IMA kernel image signature required"
  26. if [ $? -eq 1 ]; then
  27. log_info "IMA signature required"
  28. return 1
  29. fi
  30. # The architecture specific or a custom policy may require the
  31. # kexec kernel image be signed. Policy rules are walked
  32. # sequentially. As a result, a policy rule may be defined, but
  33. # might not necessarily be used. This test assumes if a policy
  34. # rule is specified, that is the intent.
  35. # First check for appended signature (modsig), then xattr
  36. if [ $ima_read_policy -eq 1 ]; then
  37. check_ima_policy "appraise" "func=KEXEC_KERNEL_CHECK" \
  38. "appraise_type=imasig|modsig"
  39. ret=$?
  40. if [ $ret -eq 1 ]; then
  41. log_info "IMA or appended(modsig) signature required"
  42. else
  43. check_ima_policy "appraise" "func=KEXEC_KERNEL_CHECK" \
  44. "appraise_type=imasig"
  45. ret=$?
  46. [ $ret -eq 1 ] && log_info "IMA signature required";
  47. fi
  48. fi
  49. return $ret
  50. }
  51. # The kexec_file_load_test() is complicated enough, require pesign.
  52. # Return 1 for PE signature found and 0 for not found.
  53. check_for_pesig()
  54. {
  55. which pesign > /dev/null 2>&1 || log_skip "pesign not found"
  56. pesign -i $KERNEL_IMAGE --show-signature | grep -q "No signatures"
  57. local ret=$?
  58. if [ $ret -eq 1 ]; then
  59. log_info "kexec kernel image PE signed"
  60. else
  61. log_info "kexec kernel image not PE signed"
  62. fi
  63. return $ret
  64. }
  65. # The kexec_file_load_test() is complicated enough, require getfattr.
  66. # Return 1 for IMA signature found and 0 for not found.
  67. check_for_imasig()
  68. {
  69. local ret=0
  70. which getfattr > /dev/null 2>&1
  71. if [ $? -eq 1 ]; then
  72. log_skip "getfattr not found"
  73. fi
  74. line=$(getfattr -n security.ima -e hex --absolute-names $KERNEL_IMAGE 2>&1)
  75. echo $line | grep -q "security.ima=0x03"
  76. if [ $? -eq 0 ]; then
  77. ret=1
  78. log_info "kexec kernel image IMA signed"
  79. else
  80. log_info "kexec kernel image not IMA signed"
  81. fi
  82. return $ret
  83. }
  84. # Return 1 for appended signature (modsig) found and 0 for not found.
  85. check_for_modsig()
  86. {
  87. local module_sig_string="~Module signature appended~"
  88. local ret=0
  89. tail --bytes $((${#module_sig_string} + 1)) $KERNEL_IMAGE | \
  90. grep -q "$module_sig_string"
  91. if [ $? -eq 0 ]; then
  92. ret=1
  93. log_info "kexec kernel image modsig signed"
  94. else
  95. log_info "kexec kernel image not modsig signed"
  96. fi
  97. return $ret
  98. }
  99. kexec_file_load_test()
  100. {
  101. local succeed_msg="kexec_file_load succeeded"
  102. local failed_msg="kexec_file_load failed"
  103. local key_msg="try enabling the CONFIG_INTEGRITY_PLATFORM_KEYRING"
  104. line=$(kexec --load --kexec-file-syscall $KERNEL_IMAGE 2>&1)
  105. if [ $? -eq 0 ]; then
  106. kexec --unload --kexec-file-syscall
  107. # In secureboot mode with an architecture specific
  108. # policy, make sure either an IMA or PE signature exists.
  109. if [ $secureboot -eq 1 ] && [ $arch_policy -eq 1 ] && \
  110. [ $ima_signed -eq 0 ] && [ $pe_signed -eq 0 ] \
  111. && [ $ima_modsig -eq 0 ]; then
  112. log_fail "$succeed_msg (missing sig)"
  113. fi
  114. if [ $kexec_sig_required -eq 1 -o $pe_sig_required -eq 1 ] \
  115. && [ $pe_signed -eq 0 ]; then
  116. log_fail "$succeed_msg (missing PE sig)"
  117. fi
  118. if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ] \
  119. && [ $ima_modsig -eq 0 ]; then
  120. log_fail "$succeed_msg (missing IMA sig)"
  121. fi
  122. if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \
  123. && [ $ima_sig_required -eq 0 ] && [ $ima_signed -eq 0 ] \
  124. && [ $ima_read_policy -eq 0 ]; then
  125. log_fail "$succeed_msg (possibly missing IMA sig)"
  126. fi
  127. if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 0 ]; then
  128. log_info "No signature verification required"
  129. elif [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \
  130. && [ $ima_sig_required -eq 0 ] && [ $ima_signed -eq 0 ] \
  131. && [ $ima_read_policy -eq 1 ]; then
  132. log_info "No signature verification required"
  133. fi
  134. log_pass "$succeed_msg"
  135. fi
  136. # Check the reason for the kexec_file_load failure
  137. echo $line | grep -q "Required key not available"
  138. if [ $? -eq 0 ]; then
  139. if [ $platform_keyring -eq 0 ]; then
  140. log_pass "$failed_msg (-ENOKEY), $key_msg"
  141. else
  142. log_pass "$failed_msg (-ENOKEY)"
  143. fi
  144. fi
  145. if [ $kexec_sig_required -eq 1 -o $pe_sig_required -eq 1 ] \
  146. && [ $pe_signed -eq 0 ]; then
  147. log_pass "$failed_msg (missing PE sig)"
  148. fi
  149. if [ $ima_sig_required -eq 1 ] && [ $ima_signed -eq 0 ]; then
  150. log_pass "$failed_msg (missing IMA sig)"
  151. fi
  152. if [ $pe_sig_required -eq 0 ] && [ $ima_appraise -eq 1 ] \
  153. && [ $ima_sig_required -eq 0 ] && [ $ima_read_policy -eq 0 ] \
  154. && [ $ima_signed -eq 0 ]; then
  155. log_pass "$failed_msg (possibly missing IMA sig)"
  156. fi
  157. log_pass "$failed_msg"
  158. return 0
  159. }
  160. # kexec requires root privileges
  161. require_root_privileges
  162. # get the kernel config
  163. get_kconfig
  164. kconfig_enabled "CONFIG_KEXEC_FILE=y" "kexec_file_load is enabled"
  165. if [ $? -eq 0 ]; then
  166. log_skip "kexec_file_load is not enabled"
  167. fi
  168. # Determine which kernel config options are enabled
  169. kconfig_enabled "CONFIG_IMA_APPRAISE=y" "IMA enabled"
  170. ima_appraise=$?
  171. kconfig_enabled "CONFIG_IMA_ARCH_POLICY=y" \
  172. "architecture specific policy enabled"
  173. arch_policy=$?
  174. kconfig_enabled "CONFIG_INTEGRITY_PLATFORM_KEYRING=y" \
  175. "platform keyring enabled"
  176. platform_keyring=$?
  177. kconfig_enabled "CONFIG_IMA_READ_POLICY=y" "reading IMA policy permitted"
  178. ima_read_policy=$?
  179. kconfig_enabled "CONFIG_KEXEC_SIG_FORCE=y" \
  180. "kexec signed kernel image required"
  181. kexec_sig_required=$?
  182. kconfig_enabled "CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y" \
  183. "PE signed kernel image required"
  184. pe_sig_required=$?
  185. is_ima_sig_required
  186. ima_sig_required=$?
  187. get_secureboot_mode
  188. secureboot=$?
  189. # Are there pe and ima signatures
  190. if [ "$(get_arch)" == 'ppc64le' ]; then
  191. pe_signed=0
  192. else
  193. check_for_pesig
  194. pe_signed=$?
  195. fi
  196. check_for_imasig
  197. ima_signed=$?
  198. check_for_modsig
  199. ima_modsig=$?
  200. # Test loading the kernel image via kexec_file_load syscall
  201. kexec_file_load_test