Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'next-integrity' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity into next-integrity

From Mimi:

In Linux 4.19, a new LSM hook named security_kernel_load_data was
upstreamed, allowing LSMs and IMA to prevent the kexec_load
syscall.  Different signature verification methods exist for verifying
the kexec'ed kernel image.  This pull request adds additional support
in IMA to prevent loading unsigned kernel images via the kexec_load
syscall, independently of the IMA policy rules, based on the runtime
"secure boot" flag.  An initial IMA kselftest is included.

In addition, this pull request defines a new, separate keyring named
".platform" for storing the preboot/firmware keys needed for verifying
the kexec'ed kernel image's signature and includes the associated IMA
kexec usage of the ".platform" keyring.

(David Howell's and Josh Boyer's patches for reading the
preboot/firmware keys, which were previously posted for a different
use case scenario, are included here.)

+863 -93
+30 -1
Documentation/security/keys/trusted-encrypted.rst
··· 18 18 when the kernel and initramfs are updated. The same key can have many saved 19 19 blobs under different PCR values, so multiple boots are easily supported. 20 20 21 + TPM 1.2 22 + ------- 23 + 21 24 By default, trusted keys are sealed under the SRK, which has the default 22 25 authorization value (20 zeros). This can be set at takeownership time with the 23 26 trouser's utility: "tpm_takeownership -u -z". 27 + 28 + TPM 2.0 29 + ------- 30 + 31 + The user must first create a storage key and make it persistent, so the key is 32 + available after reboot. This can be done using the following commands. 33 + 34 + With the IBM TSS 2 stack:: 35 + 36 + #> tsscreateprimary -hi o -st 37 + Handle 80000000 38 + #> tssevictcontrol -hi o -ho 80000000 -hp 81000001 39 + 40 + Or with the Intel TSS 2 stack:: 41 + 42 + #> tpm2_createprimary --hierarchy o -G rsa2048 -o key.ctxt 43 + [...] 44 + handle: 0x800000FF 45 + #> tpm2_evictcontrol -c key.ctxt -p 0x81000001 46 + persistentHandle: 0x81000001 24 47 25 48 Usage:: 26 49 ··· 53 30 keyctl print keyid 54 31 55 32 options: 56 - keyhandle= ascii hex value of sealing key default 0x40000000 (SRK) 33 + keyhandle= ascii hex value of sealing key 34 + TPM 1.2: default 0x40000000 (SRK) 35 + TPM 2.0: no default; must be passed every time 57 36 keyauth= ascii hex auth for sealing key default 0x00...i 58 37 (40 ascii zeros) 59 38 blobauth= ascii hex auth for sealed data default 0x00... ··· 108 83 Examples of trusted and encrypted key usage: 109 84 110 85 Create and save a trusted key named "kmk" of length 32 bytes:: 86 + 87 + Note: When using a TPM 2.0 with a persistent key with handle 0x81000001, 88 + append 'keyhandle=0x81000001' to statements between quotes, such as 89 + "new 32 keyhandle=0x81000001". 111 90 112 91 $ keyctl add trusted kmk "new 32" @u 113 92 440502848
+4
arch/x86/kernel/Makefile
··· 150 150 obj-$(CONFIG_MMCONF_FAM10H) += mmconf-fam10h_64.o 151 151 obj-y += vsmp_64.o 152 152 endif 153 + 154 + ifdef CONFIG_EFI 155 + obj-$(CONFIG_IMA) += ima_arch.o 156 + endif
+75
arch/x86/kernel/ima_arch.c
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * Copyright (C) 2018 IBM Corporation 4 + */ 5 + #include <linux/efi.h> 6 + #include <linux/ima.h> 7 + 8 + extern struct boot_params boot_params; 9 + 10 + static enum efi_secureboot_mode get_sb_mode(void) 11 + { 12 + efi_char16_t efi_SecureBoot_name[] = L"SecureBoot"; 13 + efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID; 14 + efi_status_t status; 15 + unsigned long size; 16 + u8 secboot; 17 + 18 + size = sizeof(secboot); 19 + 20 + /* Get variable contents into buffer */ 21 + status = efi.get_variable(efi_SecureBoot_name, &efi_variable_guid, 22 + NULL, &size, &secboot); 23 + if (status == EFI_NOT_FOUND) { 24 + pr_info("ima: secureboot mode disabled\n"); 25 + return efi_secureboot_mode_disabled; 26 + } 27 + 28 + if (status != EFI_SUCCESS) { 29 + pr_info("ima: secureboot mode unknown\n"); 30 + return efi_secureboot_mode_unknown; 31 + } 32 + 33 + if (secboot == 0) { 34 + pr_info("ima: secureboot mode disabled\n"); 35 + return efi_secureboot_mode_disabled; 36 + } 37 + 38 + pr_info("ima: secureboot mode enabled\n"); 39 + return efi_secureboot_mode_enabled; 40 + } 41 + 42 + bool arch_ima_get_secureboot(void) 43 + { 44 + static enum efi_secureboot_mode sb_mode; 45 + static bool initialized; 46 + 47 + if (!initialized && efi_enabled(EFI_BOOT)) { 48 + sb_mode = boot_params.secure_boot; 49 + 50 + if (sb_mode == efi_secureboot_mode_unset) 51 + sb_mode = get_sb_mode(); 52 + initialized = true; 53 + } 54 + 55 + if (sb_mode == efi_secureboot_mode_enabled) 56 + return true; 57 + else 58 + return false; 59 + } 60 + 61 + /* secureboot arch rules */ 62 + static const char * const sb_arch_rules[] = { 63 + #if !IS_ENABLED(CONFIG_KEXEC_VERIFY_SIG) 64 + "appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig", 65 + #endif /* CONFIG_KEXEC_VERIFY_SIG */ 66 + "measure func=KEXEC_KERNEL_CHECK", 67 + NULL 68 + }; 69 + 70 + const char * const *arch_get_ima_policy(void) 71 + { 72 + if (IS_ENABLED(CONFIG_IMA_ARCH_POLICY) && arch_ima_get_secureboot()) 73 + return sb_arch_rules; 74 + return NULL; 75 + }
+34
include/linux/efi.h
··· 663 663 #define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f) 664 664 #define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) 665 665 666 + #define EFI_CERT_SHA256_GUID EFI_GUID(0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28) 667 + #define EFI_CERT_X509_GUID EFI_GUID(0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72) 668 + #define EFI_CERT_X509_SHA256_GUID EFI_GUID(0x3bd2a492, 0x96c0, 0x4079, 0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed) 669 + 666 670 /* 667 671 * This GUID is used to pass to the kernel proper the struct screen_info 668 672 * structure that was populated by the stub based on the GOP protocol instance ··· 938 934 efi_memory_desc_t entry[0]; 939 935 } efi_memory_attributes_table_t; 940 936 937 + typedef struct { 938 + efi_guid_t signature_owner; 939 + u8 signature_data[]; 940 + } efi_signature_data_t; 941 + 942 + typedef struct { 943 + efi_guid_t signature_type; 944 + u32 signature_list_size; 945 + u32 signature_header_size; 946 + u32 signature_size; 947 + u8 signature_header[]; 948 + /* efi_signature_data_t signatures[][] */ 949 + } efi_signature_list_t; 950 + 951 + typedef u8 efi_sha256_hash_t[32]; 952 + 953 + typedef struct { 954 + efi_sha256_hash_t to_be_signed_hash; 955 + efi_time_t time_of_revocation; 956 + } efi_cert_x509_sha256_t; 957 + 941 958 /* 942 959 * All runtime access to EFI goes through this structure: 943 960 */ ··· 1140 1115 */ 1141 1116 char * __init efi_md_typeattr_format(char *buf, size_t size, 1142 1117 const efi_memory_desc_t *md); 1118 + 1119 + 1120 + typedef void (*efi_element_handler_t)(const char *source, 1121 + const void *element_data, 1122 + size_t element_size); 1123 + extern int __init parse_efi_signature_list( 1124 + const char *source, 1125 + const void *data, size_t size, 1126 + efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *)); 1143 1127 1144 1128 /** 1145 1129 * efi_range_is_wc - check the WC bit on an address range
+15
include/linux/ima.h
··· 30 30 extern void ima_add_kexec_buffer(struct kimage *image); 31 31 #endif 32 32 33 + #if defined(CONFIG_X86) && defined(CONFIG_EFI) 34 + extern bool arch_ima_get_secureboot(void); 35 + extern const char * const *arch_get_ima_policy(void); 36 + #else 37 + static inline bool arch_ima_get_secureboot(void) 38 + { 39 + return false; 40 + } 41 + 42 + static inline const char * const *arch_get_ima_policy(void) 43 + { 44 + return NULL; 45 + } 46 + #endif 47 + 33 48 #else 34 49 static inline int ima_bprm_check(struct linux_binprm *bprm) 35 50 {
+11
security/integrity/Kconfig
··· 51 51 .evm keyrings be signed by a key on the system trusted 52 52 keyring. 53 53 54 + config INTEGRITY_PLATFORM_KEYRING 55 + bool "Provide keyring for platform/firmware trusted keys" 56 + depends on INTEGRITY_ASYMMETRIC_KEYS 57 + depends on SYSTEM_BLACKLIST_KEYRING 58 + depends on EFI 59 + help 60 + Provide a separate, distinct keyring for platform trusted keys, which 61 + the kernel automatically populates during initialization from values 62 + provided by the platform for verifying the kexec'ed kerned image 63 + and, possibly, the initramfs signature. 64 + 54 65 config INTEGRITY_AUDIT 55 66 bool "Enables integrity auditing support " 56 67 depends on AUDIT
+5
security/integrity/Makefile
··· 9 9 integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o 10 10 integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o 11 11 integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o 12 + integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o \ 13 + platform_certs/efi_parser.o \ 14 + platform_certs/load_uefi.o 15 + obj-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/load_uefi.o 16 + $(obj)/load_uefi.o: KBUILD_CFLAGS += -fshort-wchar 12 17 13 18 subdir-$(CONFIG_IMA) += ima 14 19 obj-$(CONFIG_IMA) += ima/
+73 -37
security/integrity/digsig.c
··· 35 35 ".ima", 36 36 #endif 37 37 "_module", 38 + ".platform", 38 39 }; 39 40 40 41 #ifdef CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY ··· 74 73 return -EOPNOTSUPP; 75 74 } 76 75 77 - int __init integrity_init_keyring(const unsigned int id) 76 + static int __integrity_init_keyring(const unsigned int id, key_perm_t perm, 77 + struct key_restriction *restriction) 78 78 { 79 79 const struct cred *cred = current_cred(); 80 - struct key_restriction *restriction; 81 80 int err = 0; 81 + 82 + keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), 83 + KGIDT_INIT(0), cred, perm, 84 + KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL); 85 + if (IS_ERR(keyring[id])) { 86 + err = PTR_ERR(keyring[id]); 87 + pr_info("Can't allocate %s keyring (%d)\n", 88 + keyring_name[id], err); 89 + keyring[id] = NULL; 90 + } 91 + 92 + return err; 93 + } 94 + 95 + int __init integrity_init_keyring(const unsigned int id) 96 + { 97 + struct key_restriction *restriction; 98 + key_perm_t perm; 99 + 100 + perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW 101 + | KEY_USR_READ | KEY_USR_SEARCH; 102 + 103 + if (id == INTEGRITY_KEYRING_PLATFORM) { 104 + restriction = NULL; 105 + goto out; 106 + } 82 107 83 108 if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING)) 84 109 return 0; ··· 114 87 return -ENOMEM; 115 88 116 89 restriction->check = restrict_link_to_ima; 90 + perm |= KEY_USR_WRITE; 117 91 118 - keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), 119 - KGIDT_INIT(0), cred, 120 - ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 121 - KEY_USR_VIEW | KEY_USR_READ | 122 - KEY_USR_WRITE | KEY_USR_SEARCH), 123 - KEY_ALLOC_NOT_IN_QUOTA, 124 - restriction, NULL); 125 - if (IS_ERR(keyring[id])) { 126 - err = PTR_ERR(keyring[id]); 127 - pr_info("Can't allocate %s keyring (%d)\n", 128 - keyring_name[id], err); 129 - keyring[id] = NULL; 92 + out: 93 + return __integrity_init_keyring(id, perm, restriction); 94 + } 95 + 96 + int __init integrity_add_key(const unsigned int id, const void *data, 97 + off_t size, key_perm_t perm) 98 + { 99 + key_ref_t key; 100 + int rc = 0; 101 + 102 + if (!keyring[id]) 103 + return -EINVAL; 104 + 105 + key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric", 106 + NULL, data, size, perm, 107 + KEY_ALLOC_NOT_IN_QUOTA); 108 + if (IS_ERR(key)) { 109 + rc = PTR_ERR(key); 110 + pr_err("Problem loading X.509 certificate %d\n", rc); 111 + } else { 112 + pr_notice("Loaded X.509 cert '%s'\n", 113 + key_ref_to_ptr(key)->description); 114 + key_ref_put(key); 130 115 } 131 - return err; 116 + 117 + return rc; 118 + 132 119 } 133 120 134 121 int __init integrity_load_x509(const unsigned int id, const char *path) 135 122 { 136 - key_ref_t key; 137 123 void *data; 138 124 loff_t size; 139 125 int rc; 140 - 141 - if (!keyring[id]) 142 - return -EINVAL; 126 + key_perm_t perm; 143 127 144 128 rc = kernel_read_file_from_path(path, &data, &size, 0, 145 129 READING_X509_CERTIFICATE); ··· 159 121 return rc; 160 122 } 161 123 162 - key = key_create_or_update(make_key_ref(keyring[id], 1), 163 - "asymmetric", 164 - NULL, 165 - data, 166 - size, 167 - ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 168 - KEY_USR_VIEW | KEY_USR_READ), 169 - KEY_ALLOC_NOT_IN_QUOTA); 170 - if (IS_ERR(key)) { 171 - rc = PTR_ERR(key); 172 - pr_err("Problem loading X.509 certificate (%d): %s\n", 173 - rc, path); 174 - } else { 175 - pr_notice("Loaded X.509 cert '%s': %s\n", 176 - key_ref_to_ptr(key)->description, path); 177 - key_ref_put(key); 178 - } 124 + perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ; 125 + 126 + pr_info("Loading X.509 certificate: %s\n", path); 127 + rc = integrity_add_key(id, (const void *)data, size, perm); 128 + 179 129 vfree(data); 180 - return 0; 130 + return rc; 131 + } 132 + 133 + int __init integrity_load_cert(const unsigned int id, const char *source, 134 + const void *data, size_t len, key_perm_t perm) 135 + { 136 + if (!data) 137 + return -EINVAL; 138 + 139 + pr_info("Loading X.509 certificate: %s\n", source); 140 + return integrity_add_key(id, data, len, perm); 181 141 }
+9 -1
security/integrity/ima/Kconfig
··· 157 157 <http://linux-ima.sourceforge.net> 158 158 If unsure, say N. 159 159 160 + config IMA_ARCH_POLICY 161 + bool "Enable loading an IMA architecture specific policy" 162 + depends on KEXEC_VERIFY_SIG || IMA_APPRAISE && INTEGRITY_ASYMMETRIC_KEYS 163 + default n 164 + help 165 + This option enables loading an IMA architecture specific policy 166 + based on run time secure boot flags. 167 + 160 168 config IMA_APPRAISE_BUILD_POLICY 161 169 bool "IMA build time configured policy rules" 162 170 depends on IMA_APPRAISE && INTEGRITY_ASYMMETRIC_KEYS ··· 225 217 226 218 config IMA_APPRAISE_BOOTPARAM 227 219 bool "ima_appraise boot parameter" 228 - depends on IMA_APPRAISE 220 + depends on IMA_APPRAISE && !IMA_ARCH_POLICY 229 221 default y 230 222 help 231 223 This option enables the different "ima_appraise=" modes
+12 -2
security/integrity/ima/ima_appraise.c
··· 289 289 case EVM_IMA_XATTR_DIGSIG: 290 290 set_bit(IMA_DIGSIG, &iint->atomic_flags); 291 291 rc = integrity_digsig_verify(INTEGRITY_KEYRING_IMA, 292 - (const char *)xattr_value, rc, 292 + (const char *)xattr_value, 293 + xattr_len, 293 294 iint->ima_hash->digest, 294 295 iint->ima_hash->length); 295 296 if (rc == -EOPNOTSUPP) { 296 297 status = INTEGRITY_UNKNOWN; 297 - } else if (rc) { 298 + break; 299 + } 300 + if (IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING) && rc && 301 + func == KEXEC_KERNEL_CHECK) 302 + rc = integrity_digsig_verify(INTEGRITY_KEYRING_PLATFORM, 303 + (const char *)xattr_value, 304 + xattr_len, 305 + iint->ima_hash->digest, 306 + iint->ima_hash->length); 307 + if (rc) { 298 308 cause = "invalid-signature"; 299 309 status = INTEGRITY_FAIL; 300 310 } else {
+14 -7
security/integrity/ima/ima_main.c
··· 105 105 } else { 106 106 if (must_measure) 107 107 set_bit(IMA_MUST_MEASURE, &iint->atomic_flags); 108 - if ((atomic_read(&inode->i_writecount) > 0) && must_measure) 108 + if (inode_is_open_for_write(inode) && must_measure) 109 109 send_writers = true; 110 110 } 111 111 ··· 507 507 */ 508 508 int ima_load_data(enum kernel_load_data_id id) 509 509 { 510 - bool sig_enforce; 510 + bool ima_enforce, sig_enforce; 511 511 512 - if ((ima_appraise & IMA_APPRAISE_ENFORCE) != IMA_APPRAISE_ENFORCE) 513 - return 0; 512 + ima_enforce = 513 + (ima_appraise & IMA_APPRAISE_ENFORCE) == IMA_APPRAISE_ENFORCE; 514 514 515 515 switch (id) { 516 516 case LOADING_KEXEC_IMAGE: 517 - if (ima_appraise & IMA_APPRAISE_KEXEC) { 517 + if (IS_ENABLED(CONFIG_KEXEC_VERIFY_SIG) 518 + && arch_ima_get_secureboot()) { 519 + pr_err("impossible to appraise a kernel image without a file descriptor; try using kexec_file_load syscall.\n"); 520 + return -EACCES; 521 + } 522 + 523 + if (ima_enforce && (ima_appraise & IMA_APPRAISE_KEXEC)) { 518 524 pr_err("impossible to appraise a kernel image without a file descriptor; try using kexec_file_load syscall.\n"); 519 525 return -EACCES; /* INTEGRITY_UNKNOWN */ 520 526 } 521 527 break; 522 528 case LOADING_FIRMWARE: 523 - if (ima_appraise & IMA_APPRAISE_FIRMWARE) { 529 + if (ima_enforce && (ima_appraise & IMA_APPRAISE_FIRMWARE)) { 524 530 pr_err("Prevent firmware sysfs fallback loading.\n"); 525 531 return -EACCES; /* INTEGRITY_UNKNOWN */ 526 532 } ··· 534 528 case LOADING_MODULE: 535 529 sig_enforce = is_module_sig_enforced(); 536 530 537 - if (!sig_enforce && (ima_appraise & IMA_APPRAISE_MODULES)) { 531 + if (ima_enforce && (!sig_enforce 532 + && (ima_appraise & IMA_APPRAISE_MODULES))) { 538 533 pr_err("impossible to appraise a module without a file descriptor. sig_enforce kernel parameter might help\n"); 539 534 return -EACCES; /* INTEGRITY_UNKNOWN */ 540 535 }
+129 -44
security/integrity/ima/ima_policy.c
··· 20 20 #include <linux/rculist.h> 21 21 #include <linux/genhd.h> 22 22 #include <linux/seq_file.h> 23 + #include <linux/ima.h> 23 24 24 25 #include "ima.h" 25 26 ··· 58 57 }; 59 58 60 59 enum policy_types { ORIGINAL_TCB = 1, DEFAULT_TCB }; 60 + 61 + enum policy_rule_list { IMA_DEFAULT_POLICY = 1, IMA_CUSTOM_POLICY }; 61 62 62 63 struct ima_rule_entry { 63 64 struct list_head list; ··· 107 104 .flags = IMA_FSMAGIC}, 108 105 {.action = DONT_MEASURE, .fsmagic = CGROUP2_SUPER_MAGIC, 109 106 .flags = IMA_FSMAGIC}, 110 - {.action = DONT_MEASURE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC} 107 + {.action = DONT_MEASURE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC}, 108 + {.action = DONT_MEASURE, .fsmagic = EFIVARFS_MAGIC, .flags = IMA_FSMAGIC} 111 109 }; 112 110 113 111 static struct ima_rule_entry original_measurement_rules[] __ro_after_init = { ··· 151 147 {.action = DONT_APPRAISE, .fsmagic = SELINUX_MAGIC, .flags = IMA_FSMAGIC}, 152 148 {.action = DONT_APPRAISE, .fsmagic = SMACK_MAGIC, .flags = IMA_FSMAGIC}, 153 149 {.action = DONT_APPRAISE, .fsmagic = NSFS_MAGIC, .flags = IMA_FSMAGIC}, 150 + {.action = DONT_APPRAISE, .fsmagic = EFIVARFS_MAGIC, .flags = IMA_FSMAGIC}, 154 151 {.action = DONT_APPRAISE, .fsmagic = CGROUP_SUPER_MAGIC, .flags = IMA_FSMAGIC}, 155 152 {.action = DONT_APPRAISE, .fsmagic = CGROUP2_SUPER_MAGIC, .flags = IMA_FSMAGIC}, 156 153 #ifdef CONFIG_IMA_WRITE_POLICY ··· 197 192 {.action = APPRAISE, .func = POLICY_CHECK, 198 193 .flags = IMA_FUNC | IMA_DIGSIG_REQUIRED}, 199 194 }; 195 + 196 + /* An array of architecture specific rules */ 197 + struct ima_rule_entry *arch_policy_entry __ro_after_init; 200 198 201 199 static LIST_HEAD(ima_default_rules); 202 200 static LIST_HEAD(ima_policy_rules); ··· 481 473 return 0; 482 474 } 483 475 476 + static void add_rules(struct ima_rule_entry *entries, int count, 477 + enum policy_rule_list policy_rule) 478 + { 479 + int i = 0; 480 + 481 + for (i = 0; i < count; i++) { 482 + struct ima_rule_entry *entry; 483 + 484 + if (policy_rule & IMA_DEFAULT_POLICY) 485 + list_add_tail(&entries[i].list, &ima_default_rules); 486 + 487 + if (policy_rule & IMA_CUSTOM_POLICY) { 488 + entry = kmemdup(&entries[i], sizeof(*entry), 489 + GFP_KERNEL); 490 + if (!entry) 491 + continue; 492 + 493 + list_add_tail(&entry->list, &ima_policy_rules); 494 + } 495 + if (entries[i].action == APPRAISE) 496 + temp_ima_appraise |= ima_appraise_flag(entries[i].func); 497 + if (entries[i].func == POLICY_CHECK) 498 + temp_ima_appraise |= IMA_APPRAISE_POLICY; 499 + } 500 + } 501 + 502 + static int ima_parse_rule(char *rule, struct ima_rule_entry *entry); 503 + 504 + static int __init ima_init_arch_policy(void) 505 + { 506 + const char * const *arch_rules; 507 + const char * const *rules; 508 + int arch_entries = 0; 509 + int i = 0; 510 + 511 + arch_rules = arch_get_ima_policy(); 512 + if (!arch_rules) 513 + return arch_entries; 514 + 515 + /* Get number of rules */ 516 + for (rules = arch_rules; *rules != NULL; rules++) 517 + arch_entries++; 518 + 519 + arch_policy_entry = kcalloc(arch_entries + 1, 520 + sizeof(*arch_policy_entry), GFP_KERNEL); 521 + if (!arch_policy_entry) 522 + return 0; 523 + 524 + /* Convert each policy string rules to struct ima_rule_entry format */ 525 + for (rules = arch_rules, i = 0; *rules != NULL; rules++) { 526 + char rule[255]; 527 + int result; 528 + 529 + result = strlcpy(rule, *rules, sizeof(rule)); 530 + 531 + INIT_LIST_HEAD(&arch_policy_entry[i].list); 532 + result = ima_parse_rule(rule, &arch_policy_entry[i]); 533 + if (result) { 534 + pr_warn("Skipping unknown architecture policy rule: %s\n", 535 + rule); 536 + memset(&arch_policy_entry[i], 0, 537 + sizeof(*arch_policy_entry)); 538 + continue; 539 + } 540 + i++; 541 + } 542 + return i; 543 + } 544 + 484 545 /** 485 546 * ima_init_policy - initialize the default measure rules. 486 547 * ··· 558 481 */ 559 482 void __init ima_init_policy(void) 560 483 { 561 - int i, measure_entries, appraise_entries, secure_boot_entries; 484 + int build_appraise_entries, arch_entries; 562 485 563 - /* if !ima_policy set entries = 0 so we load NO default rules */ 564 - measure_entries = ima_policy ? ARRAY_SIZE(dont_measure_rules) : 0; 565 - appraise_entries = ima_use_appraise_tcb ? 566 - ARRAY_SIZE(default_appraise_rules) : 0; 567 - secure_boot_entries = ima_use_secure_boot ? 568 - ARRAY_SIZE(secure_boot_rules) : 0; 569 - 570 - for (i = 0; i < measure_entries; i++) 571 - list_add_tail(&dont_measure_rules[i].list, &ima_default_rules); 486 + /* if !ima_policy, we load NO default rules */ 487 + if (ima_policy) 488 + add_rules(dont_measure_rules, ARRAY_SIZE(dont_measure_rules), 489 + IMA_DEFAULT_POLICY); 572 490 573 491 switch (ima_policy) { 574 492 case ORIGINAL_TCB: 575 - for (i = 0; i < ARRAY_SIZE(original_measurement_rules); i++) 576 - list_add_tail(&original_measurement_rules[i].list, 577 - &ima_default_rules); 493 + add_rules(original_measurement_rules, 494 + ARRAY_SIZE(original_measurement_rules), 495 + IMA_DEFAULT_POLICY); 578 496 break; 579 497 case DEFAULT_TCB: 580 - for (i = 0; i < ARRAY_SIZE(default_measurement_rules); i++) 581 - list_add_tail(&default_measurement_rules[i].list, 582 - &ima_default_rules); 498 + add_rules(default_measurement_rules, 499 + ARRAY_SIZE(default_measurement_rules), 500 + IMA_DEFAULT_POLICY); 583 501 default: 584 502 break; 585 503 } 586 504 587 505 /* 588 - * Insert the builtin "secure_boot" policy rules requiring file 589 - * signatures, prior to any other appraise rules. 506 + * Based on runtime secure boot flags, insert arch specific measurement 507 + * and appraise rules requiring file signatures for both the initial 508 + * and custom policies, prior to other appraise rules. 509 + * (Highest priority) 590 510 */ 591 - for (i = 0; i < secure_boot_entries; i++) { 592 - list_add_tail(&secure_boot_rules[i].list, &ima_default_rules); 593 - temp_ima_appraise |= 594 - ima_appraise_flag(secure_boot_rules[i].func); 595 - } 511 + arch_entries = ima_init_arch_policy(); 512 + if (!arch_entries) 513 + pr_info("No architecture policies found\n"); 514 + else 515 + add_rules(arch_policy_entry, arch_entries, 516 + IMA_DEFAULT_POLICY | IMA_CUSTOM_POLICY); 517 + 518 + /* 519 + * Insert the builtin "secure_boot" policy rules requiring file 520 + * signatures, prior to other appraise rules. 521 + */ 522 + if (ima_use_secure_boot) 523 + add_rules(secure_boot_rules, ARRAY_SIZE(secure_boot_rules), 524 + IMA_DEFAULT_POLICY); 596 525 597 526 /* 598 527 * Insert the build time appraise rules requiring file signatures 599 528 * for both the initial and custom policies, prior to other appraise 600 - * rules. 529 + * rules. As the secure boot rules includes all of the build time 530 + * rules, include either one or the other set of rules, but not both. 601 531 */ 602 - for (i = 0; i < ARRAY_SIZE(build_appraise_rules); i++) { 603 - struct ima_rule_entry *entry; 604 - 605 - if (!secure_boot_entries) 606 - list_add_tail(&build_appraise_rules[i].list, 607 - &ima_default_rules); 608 - 609 - entry = kmemdup(&build_appraise_rules[i], sizeof(*entry), 610 - GFP_KERNEL); 611 - if (entry) 612 - list_add_tail(&entry->list, &ima_policy_rules); 613 - build_ima_appraise |= 614 - ima_appraise_flag(build_appraise_rules[i].func); 532 + build_appraise_entries = ARRAY_SIZE(build_appraise_rules); 533 + if (build_appraise_entries) { 534 + if (ima_use_secure_boot) 535 + add_rules(build_appraise_rules, build_appraise_entries, 536 + IMA_CUSTOM_POLICY); 537 + else 538 + add_rules(build_appraise_rules, build_appraise_entries, 539 + IMA_DEFAULT_POLICY | IMA_CUSTOM_POLICY); 615 540 } 616 541 617 - for (i = 0; i < appraise_entries; i++) { 618 - list_add_tail(&default_appraise_rules[i].list, 619 - &ima_default_rules); 620 - if (default_appraise_rules[i].func == POLICY_CHECK) 621 - temp_ima_appraise |= IMA_APPRAISE_POLICY; 622 - } 542 + if (ima_use_appraise_tcb) 543 + add_rules(default_appraise_rules, 544 + ARRAY_SIZE(default_appraise_rules), 545 + IMA_DEFAULT_POLICY); 623 546 624 547 ima_rules = &ima_default_rules; 625 548 ima_update_policy_flag(); ··· 653 576 if (ima_rules != policy) { 654 577 ima_policy_flag = 0; 655 578 ima_rules = policy; 579 + 580 + /* 581 + * IMA architecture specific policy rules are specified 582 + * as strings and converted to an array of ima_entry_rules 583 + * on boot. After loading a custom policy, free the 584 + * architecture specific rules stored as an array. 585 + */ 586 + kfree(arch_policy_entry); 656 587 } 657 588 ima_update_policy_flag(); 658 589 }
+22 -1
security/integrity/integrity.h
··· 142 142 #define INTEGRITY_KEYRING_EVM 0 143 143 #define INTEGRITY_KEYRING_IMA 1 144 144 #define INTEGRITY_KEYRING_MODULE 2 145 - #define INTEGRITY_KEYRING_MAX 3 145 + #define INTEGRITY_KEYRING_PLATFORM 3 146 + #define INTEGRITY_KEYRING_MAX 4 146 147 147 148 extern struct dentry *integrity_dir; 148 149 ··· 154 153 155 154 int __init integrity_init_keyring(const unsigned int id); 156 155 int __init integrity_load_x509(const unsigned int id, const char *path); 156 + int __init integrity_load_cert(const unsigned int id, const char *source, 157 + const void *data, size_t len, key_perm_t perm); 157 158 #else 158 159 159 160 static inline int integrity_digsig_verify(const unsigned int id, ··· 166 163 } 167 164 168 165 static inline int integrity_init_keyring(const unsigned int id) 166 + { 167 + return 0; 168 + } 169 + 170 + static inline int __init integrity_load_cert(const unsigned int id, 171 + const char *source, 172 + const void *data, size_t len, 173 + key_perm_t perm) 169 174 { 170 175 return 0; 171 176 } ··· 232 221 return NULL; 233 222 } 234 223 224 + #endif 225 + 226 + #ifdef CONFIG_INTEGRITY_PLATFORM_KEYRING 227 + void __init add_to_platform_keyring(const char *source, const void *data, 228 + size_t len); 229 + #else 230 + static inline void __init add_to_platform_keyring(const char *source, 231 + const void *data, size_t len) 232 + { 233 + } 235 234 #endif
+108
security/integrity/platform_certs/efi_parser.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* EFI signature/key/certificate list parser 3 + * 4 + * Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved. 5 + * Written by David Howells (dhowells@redhat.com) 6 + */ 7 + 8 + #define pr_fmt(fmt) "EFI: "fmt 9 + #include <linux/module.h> 10 + #include <linux/printk.h> 11 + #include <linux/err.h> 12 + #include <linux/efi.h> 13 + 14 + /** 15 + * parse_efi_signature_list - Parse an EFI signature list for certificates 16 + * @source: The source of the key 17 + * @data: The data blob to parse 18 + * @size: The size of the data blob 19 + * @get_handler_for_guid: Get the handler func for the sig type (or NULL) 20 + * 21 + * Parse an EFI signature list looking for elements of interest. A list is 22 + * made up of a series of sublists, where all the elements in a sublist are of 23 + * the same type, but sublists can be of different types. 24 + * 25 + * For each sublist encountered, the @get_handler_for_guid function is called 26 + * with the type specifier GUID and returns either a pointer to a function to 27 + * handle elements of that type or NULL if the type is not of interest. 28 + * 29 + * If the sublist is of interest, each element is passed to the handler 30 + * function in turn. 31 + * 32 + * Error EBADMSG is returned if the list doesn't parse correctly and 0 is 33 + * returned if the list was parsed correctly. No error can be returned from 34 + * the @get_handler_for_guid function or the element handler function it 35 + * returns. 36 + */ 37 + int __init parse_efi_signature_list( 38 + const char *source, 39 + const void *data, size_t size, 40 + efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *)) 41 + { 42 + efi_element_handler_t handler; 43 + unsigned int offs = 0; 44 + 45 + pr_devel("-->%s(,%zu)\n", __func__, size); 46 + 47 + while (size > 0) { 48 + const efi_signature_data_t *elem; 49 + efi_signature_list_t list; 50 + size_t lsize, esize, hsize, elsize; 51 + 52 + if (size < sizeof(list)) 53 + return -EBADMSG; 54 + 55 + memcpy(&list, data, sizeof(list)); 56 + pr_devel("LIST[%04x] guid=%pUl ls=%x hs=%x ss=%x\n", 57 + offs, 58 + list.signature_type.b, list.signature_list_size, 59 + list.signature_header_size, list.signature_size); 60 + 61 + lsize = list.signature_list_size; 62 + hsize = list.signature_header_size; 63 + esize = list.signature_size; 64 + elsize = lsize - sizeof(list) - hsize; 65 + 66 + if (lsize > size) { 67 + pr_devel("<--%s() = -EBADMSG [overrun @%x]\n", 68 + __func__, offs); 69 + return -EBADMSG; 70 + } 71 + 72 + if (lsize < sizeof(list) || 73 + lsize - sizeof(list) < hsize || 74 + esize < sizeof(*elem) || 75 + elsize < esize || 76 + elsize % esize != 0) { 77 + pr_devel("- bad size combo @%x\n", offs); 78 + return -EBADMSG; 79 + } 80 + 81 + handler = get_handler_for_guid(&list.signature_type); 82 + if (!handler) { 83 + data += lsize; 84 + size -= lsize; 85 + offs += lsize; 86 + continue; 87 + } 88 + 89 + data += sizeof(list) + hsize; 90 + size -= sizeof(list) + hsize; 91 + offs += sizeof(list) + hsize; 92 + 93 + for (; elsize > 0; elsize -= esize) { 94 + elem = data; 95 + 96 + pr_devel("ELEM[%04x]\n", offs); 97 + handler(source, 98 + &elem->signature_data, 99 + esize - sizeof(*elem)); 100 + 101 + data += esize; 102 + size -= esize; 103 + offs += esize; 104 + } 105 + } 106 + 107 + return 0; 108 + }
+194
security/integrity/platform_certs/load_uefi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/kernel.h> 4 + #include <linux/sched.h> 5 + #include <linux/cred.h> 6 + #include <linux/err.h> 7 + #include <linux/efi.h> 8 + #include <linux/slab.h> 9 + #include <keys/asymmetric-type.h> 10 + #include <keys/system_keyring.h> 11 + #include "../integrity.h" 12 + 13 + static efi_guid_t efi_cert_x509_guid __initdata = EFI_CERT_X509_GUID; 14 + static efi_guid_t efi_cert_x509_sha256_guid __initdata = 15 + EFI_CERT_X509_SHA256_GUID; 16 + static efi_guid_t efi_cert_sha256_guid __initdata = EFI_CERT_SHA256_GUID; 17 + 18 + /* 19 + * Look to see if a UEFI variable called MokIgnoreDB exists and return true if 20 + * it does. 21 + * 22 + * This UEFI variable is set by the shim if a user tells the shim to not use 23 + * the certs/hashes in the UEFI db variable for verification purposes. If it 24 + * is set, we should ignore the db variable also and the true return indicates 25 + * this. 26 + */ 27 + static __init bool uefi_check_ignore_db(void) 28 + { 29 + efi_status_t status; 30 + unsigned int db = 0; 31 + unsigned long size = sizeof(db); 32 + efi_guid_t guid = EFI_SHIM_LOCK_GUID; 33 + 34 + status = efi.get_variable(L"MokIgnoreDB", &guid, NULL, &size, &db); 35 + return status == EFI_SUCCESS; 36 + } 37 + 38 + /* 39 + * Get a certificate list blob from the named EFI variable. 40 + */ 41 + static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, 42 + unsigned long *size) 43 + { 44 + efi_status_t status; 45 + unsigned long lsize = 4; 46 + unsigned long tmpdb[4]; 47 + void *db; 48 + 49 + status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb); 50 + if (status != EFI_BUFFER_TOO_SMALL) { 51 + pr_err("Couldn't get size: 0x%lx\n", status); 52 + return NULL; 53 + } 54 + 55 + db = kmalloc(lsize, GFP_KERNEL); 56 + if (!db) 57 + return NULL; 58 + 59 + status = efi.get_variable(name, guid, NULL, &lsize, db); 60 + if (status != EFI_SUCCESS) { 61 + kfree(db); 62 + pr_err("Error reading db var: 0x%lx\n", status); 63 + return NULL; 64 + } 65 + 66 + *size = lsize; 67 + return db; 68 + } 69 + 70 + /* 71 + * Blacklist a hash. 72 + */ 73 + static __init void uefi_blacklist_hash(const char *source, const void *data, 74 + size_t len, const char *type, 75 + size_t type_len) 76 + { 77 + char *hash, *p; 78 + 79 + hash = kmalloc(type_len + len * 2 + 1, GFP_KERNEL); 80 + if (!hash) 81 + return; 82 + p = memcpy(hash, type, type_len); 83 + p += type_len; 84 + bin2hex(p, data, len); 85 + p += len * 2; 86 + *p = 0; 87 + 88 + mark_hash_blacklisted(hash); 89 + kfree(hash); 90 + } 91 + 92 + /* 93 + * Blacklist an X509 TBS hash. 94 + */ 95 + static __init void uefi_blacklist_x509_tbs(const char *source, 96 + const void *data, size_t len) 97 + { 98 + uefi_blacklist_hash(source, data, len, "tbs:", 4); 99 + } 100 + 101 + /* 102 + * Blacklist the hash of an executable. 103 + */ 104 + static __init void uefi_blacklist_binary(const char *source, 105 + const void *data, size_t len) 106 + { 107 + uefi_blacklist_hash(source, data, len, "bin:", 4); 108 + } 109 + 110 + /* 111 + * Return the appropriate handler for particular signature list types found in 112 + * the UEFI db and MokListRT tables. 113 + */ 114 + static __init efi_element_handler_t get_handler_for_db(const efi_guid_t * 115 + sig_type) 116 + { 117 + if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0) 118 + return add_to_platform_keyring; 119 + return 0; 120 + } 121 + 122 + /* 123 + * Return the appropriate handler for particular signature list types found in 124 + * the UEFI dbx and MokListXRT tables. 125 + */ 126 + static __init efi_element_handler_t get_handler_for_dbx(const efi_guid_t * 127 + sig_type) 128 + { 129 + if (efi_guidcmp(*sig_type, efi_cert_x509_sha256_guid) == 0) 130 + return uefi_blacklist_x509_tbs; 131 + if (efi_guidcmp(*sig_type, efi_cert_sha256_guid) == 0) 132 + return uefi_blacklist_binary; 133 + return 0; 134 + } 135 + 136 + /* 137 + * Load the certs contained in the UEFI databases into the platform trusted 138 + * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist 139 + * keyring. 140 + */ 141 + static int __init load_uefi_certs(void) 142 + { 143 + efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID; 144 + efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; 145 + void *db = NULL, *dbx = NULL, *mok = NULL; 146 + unsigned long dbsize = 0, dbxsize = 0, moksize = 0; 147 + int rc = 0; 148 + 149 + if (!efi.get_variable) 150 + return false; 151 + 152 + /* Get db, MokListRT, and dbx. They might not exist, so it isn't 153 + * an error if we can't get them. 154 + */ 155 + if (!uefi_check_ignore_db()) { 156 + db = get_cert_list(L"db", &secure_var, &dbsize); 157 + if (!db) { 158 + pr_err("MODSIGN: Couldn't get UEFI db list\n"); 159 + } else { 160 + rc = parse_efi_signature_list("UEFI:db", 161 + db, dbsize, get_handler_for_db); 162 + if (rc) 163 + pr_err("Couldn't parse db signatures: %d\n", 164 + rc); 165 + kfree(db); 166 + } 167 + } 168 + 169 + mok = get_cert_list(L"MokListRT", &mok_var, &moksize); 170 + if (!mok) { 171 + pr_info("Couldn't get UEFI MokListRT\n"); 172 + } else { 173 + rc = parse_efi_signature_list("UEFI:MokListRT", 174 + mok, moksize, get_handler_for_db); 175 + if (rc) 176 + pr_err("Couldn't parse MokListRT signatures: %d\n", rc); 177 + kfree(mok); 178 + } 179 + 180 + dbx = get_cert_list(L"dbx", &secure_var, &dbxsize); 181 + if (!dbx) { 182 + pr_info("Couldn't get UEFI dbx list\n"); 183 + } else { 184 + rc = parse_efi_signature_list("UEFI:dbx", 185 + dbx, dbxsize, 186 + get_handler_for_dbx); 187 + if (rc) 188 + pr_err("Couldn't parse dbx signatures: %d\n", rc); 189 + kfree(dbx); 190 + } 191 + 192 + return rc; 193 + } 194 + late_initcall(load_uefi_certs);
+58
security/integrity/platform_certs/platform_keyring.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Platform keyring for firmware/platform keys 4 + * 5 + * Copyright IBM Corporation, 2018 6 + * Author(s): Nayna Jain <nayna@linux.ibm.com> 7 + */ 8 + 9 + #include <linux/export.h> 10 + #include <linux/kernel.h> 11 + #include <linux/sched.h> 12 + #include <linux/cred.h> 13 + #include <linux/err.h> 14 + #include <linux/slab.h> 15 + #include "../integrity.h" 16 + 17 + /** 18 + * add_to_platform_keyring - Add to platform keyring without validation. 19 + * @source: Source of key 20 + * @data: The blob holding the key 21 + * @len: The length of the data blob 22 + * 23 + * Add a key to the platform keyring without checking its trust chain. This 24 + * is available only during kernel initialisation. 25 + */ 26 + void __init add_to_platform_keyring(const char *source, const void *data, 27 + size_t len) 28 + { 29 + key_perm_t perm; 30 + int rc; 31 + 32 + perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW; 33 + 34 + rc = integrity_load_cert(INTEGRITY_KEYRING_PLATFORM, source, data, len, 35 + perm); 36 + if (rc) 37 + pr_info("Error adding keys to platform keyring %s\n", source); 38 + } 39 + 40 + /* 41 + * Create the trusted keyrings. 42 + */ 43 + static __init int platform_keyring_init(void) 44 + { 45 + int rc; 46 + 47 + rc = integrity_init_keyring(INTEGRITY_KEYRING_PLATFORM); 48 + if (rc) 49 + return rc; 50 + 51 + pr_notice("Platform Keyring initialized\n"); 52 + return 0; 53 + } 54 + 55 + /* 56 + * Must be initialised before we try and load the keys into the keyring. 57 + */ 58 + device_initcall(platform_keyring_init);
+1
tools/testing/selftests/Makefile
··· 13 13 TARGETS += ftrace 14 14 TARGETS += futex 15 15 TARGETS += gpio 16 + TARGETS += ima 16 17 TARGETS += intel_pstate 17 18 TARGETS += ipc 18 19 TARGETS += kcmp
+11
tools/testing/selftests/ima/Makefile
··· 1 + # Makefile for kexec_load 2 + 3 + uname_M := $(shell uname -m 2>/dev/null || echo not) 4 + ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) 5 + 6 + ifeq ($(ARCH),x86) 7 + TEST_PROGS := test_kexec_load.sh 8 + 9 + include ../lib.mk 10 + 11 + endif
+4
tools/testing/selftests/ima/config
··· 1 + CONFIG_IMA_APPRAISE 2 + CONFIG_IMA_ARCH_POLICY 3 + CONFIG_SECURITYFS 4 + CONFIG_KEXEC_VERIFY_SIG
+54
tools/testing/selftests/ima/test_kexec_load.sh
··· 1 + #!/bin/sh 2 + # SPDX-License-Identifier: GPL-2.0+ 3 + # Loading a kernel image via the kexec_load syscall should fail 4 + # when the kerne is CONFIG_KEXEC_VERIFY_SIG enabled and the system 5 + # is booted in secureboot mode. 6 + 7 + TEST="$0" 8 + EFIVARFS="/sys/firmware/efi/efivars" 9 + rc=0 10 + 11 + # Kselftest framework requirement - SKIP code is 4. 12 + ksft_skip=4 13 + 14 + # kexec requires root privileges 15 + if [ $UID != 0 ]; then 16 + echo "$TEST: must be run as root" >&2 17 + exit $ksft_skip 18 + fi 19 + 20 + # Make sure that efivars is mounted in the normal location 21 + if ! grep -q "^\S\+ $EFIVARFS efivarfs" /proc/mounts; then 22 + echo "$TEST: efivars is not mounted on $EFIVARFS" >&2 23 + exit $ksft_skip 24 + fi 25 + 26 + # Get secureboot mode 27 + file="$EFIVARFS/SecureBoot-*" 28 + if [ ! -e $file ]; then 29 + echo "$TEST: unknown secureboot mode" >&2 30 + exit $ksft_skip 31 + fi 32 + secureboot=`hexdump $file | awk '{print substr($4,length($4),1)}'` 33 + 34 + # kexec_load should fail in secure boot mode 35 + KERNEL_IMAGE="/boot/vmlinuz-`uname -r`" 36 + kexec -l $KERNEL_IMAGE &>> /dev/null 37 + if [ $? == 0 ]; then 38 + kexec -u 39 + if [ "$secureboot" == "1" ]; then 40 + echo "$TEST: kexec_load succeeded [FAIL]" 41 + rc=1 42 + else 43 + echo "$TEST: kexec_load succeeded [PASS]" 44 + fi 45 + else 46 + if [ "$secureboot" == "1" ]; then 47 + echo "$TEST: kexec_load failed [PASS]" 48 + else 49 + echo "$TEST: kexec_load failed [FAIL]" 50 + rc=1 51 + fi 52 + fi 53 + 54 + exit $rc