Commit 9b4e40c8 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull EFI fixes from Ingo Molnar:
 "Misc EFI fixes all across the map: CPER error report fixes, fixes to
  TPM event log parsing, fix for a kexec hang, a Sparse fix and other
  fixes"

* 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  efi/tpm: Fix sanity check of unsigned tbl_size being less than zero
  efi/x86: Do not clean dummy variable in kexec path
  efi: Make unexported efi_rci2_sysfs_init() static
  efi/tpm: Only set 'efi_tpm_final_log_size' after successful event log parsing
  efi/tpm: Don't traverse an event log with no events
  efi/tpm: Don't access event->count when it isn't mapped
  efivar/ssdt: Don't iterate over EFI vars if no SSDT override was specified
  efi/cper: Fix endianness of PCIe class code
parents fcb45a28 be59d57f
...@@ -917,9 +917,6 @@ static void __init kexec_enter_virtual_mode(void) ...@@ -917,9 +917,6 @@ static void __init kexec_enter_virtual_mode(void)
if (efi_enabled(EFI_OLD_MEMMAP) && (__supported_pte_mask & _PAGE_NX)) if (efi_enabled(EFI_OLD_MEMMAP) && (__supported_pte_mask & _PAGE_NX))
runtime_code_page_mkexec(); runtime_code_page_mkexec();
/* clean DUMMY object */
efi_delete_dummy_variable();
#endif #endif
} }
......
...@@ -381,7 +381,7 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, ...@@ -381,7 +381,7 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
printk("%s""vendor_id: 0x%04x, device_id: 0x%04x\n", pfx, printk("%s""vendor_id: 0x%04x, device_id: 0x%04x\n", pfx,
pcie->device_id.vendor_id, pcie->device_id.device_id); pcie->device_id.vendor_id, pcie->device_id.device_id);
p = pcie->device_id.class_code; p = pcie->device_id.class_code;
printk("%s""class_code: %02x%02x%02x\n", pfx, p[0], p[1], p[2]); printk("%s""class_code: %02x%02x%02x\n", pfx, p[2], p[1], p[0]);
} }
if (pcie->validation_bits & CPER_PCIE_VALID_SERIAL_NUMBER) if (pcie->validation_bits & CPER_PCIE_VALID_SERIAL_NUMBER)
printk("%s""serial number: 0x%04x, 0x%04x\n", pfx, printk("%s""serial number: 0x%04x, 0x%04x\n", pfx,
......
...@@ -267,6 +267,9 @@ static __init int efivar_ssdt_load(void) ...@@ -267,6 +267,9 @@ static __init int efivar_ssdt_load(void)
void *data; void *data;
int ret; int ret;
if (!efivar_ssdt[0])
return 0;
ret = efivar_init(efivar_ssdt_iter, &entries, true, &entries); ret = efivar_init(efivar_ssdt_iter, &entries, true, &entries);
list_for_each_entry_safe(entry, aux, &entries, list) { list_for_each_entry_safe(entry, aux, &entries, list) {
......
...@@ -76,7 +76,7 @@ static u16 checksum(void) ...@@ -76,7 +76,7 @@ static u16 checksum(void)
return chksum; return chksum;
} }
int __init efi_rci2_sysfs_init(void) static int __init efi_rci2_sysfs_init(void)
{ {
struct kobject *tables_kobj; struct kobject *tables_kobj;
int ret = -ENOMEM; int ret = -ENOMEM;
......
...@@ -40,7 +40,7 @@ int __init efi_tpm_eventlog_init(void) ...@@ -40,7 +40,7 @@ int __init efi_tpm_eventlog_init(void)
{ {
struct linux_efi_tpm_eventlog *log_tbl; struct linux_efi_tpm_eventlog *log_tbl;
struct efi_tcg2_final_events_table *final_tbl; struct efi_tcg2_final_events_table *final_tbl;
unsigned int tbl_size; int tbl_size;
int ret = 0; int ret = 0;
if (efi.tpm_log == EFI_INVALID_TABLE_ADDR) { if (efi.tpm_log == EFI_INVALID_TABLE_ADDR) {
...@@ -75,16 +75,28 @@ int __init efi_tpm_eventlog_init(void) ...@@ -75,16 +75,28 @@ int __init efi_tpm_eventlog_init(void)
goto out; goto out;
} }
tbl_size = tpm2_calc_event_log_size((void *)efi.tpm_final_log tbl_size = 0;
if (final_tbl->nr_events != 0) {
void *events = (void *)efi.tpm_final_log
+ sizeof(final_tbl->version) + sizeof(final_tbl->version)
+ sizeof(final_tbl->nr_events), + sizeof(final_tbl->nr_events);
tbl_size = tpm2_calc_event_log_size(events,
final_tbl->nr_events, final_tbl->nr_events,
log_tbl->log); log_tbl->log);
}
if (tbl_size < 0) {
pr_err(FW_BUG "Failed to parse event in TPM Final Events Log\n");
goto out_calc;
}
memblock_reserve((unsigned long)final_tbl, memblock_reserve((unsigned long)final_tbl,
tbl_size + sizeof(*final_tbl)); tbl_size + sizeof(*final_tbl));
early_memunmap(final_tbl, sizeof(*final_tbl));
efi_tpm_final_log_size = tbl_size; efi_tpm_final_log_size = tbl_size;
out_calc:
early_memunmap(final_tbl, sizeof(*final_tbl));
out: out:
early_memunmap(log_tbl, sizeof(*log_tbl)); early_memunmap(log_tbl, sizeof(*log_tbl));
return ret; return ret;
......
...@@ -152,7 +152,7 @@ struct tcg_algorithm_info { ...@@ -152,7 +152,7 @@ struct tcg_algorithm_info {
* total. Once we've done this we know the offset of the data length field, * total. Once we've done this we know the offset of the data length field,
* and can calculate the total size of the event. * and can calculate the total size of the event.
* *
* Return: size of the event on success, <0 on failure * Return: size of the event on success, 0 on failure
*/ */
static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event, static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
...@@ -170,6 +170,7 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event, ...@@ -170,6 +170,7 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
u16 halg; u16 halg;
int i; int i;
int j; int j;
u32 count, event_type;
marker = event; marker = event;
marker_start = marker; marker_start = marker;
...@@ -190,16 +191,22 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event, ...@@ -190,16 +191,22 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
} }
event = (struct tcg_pcr_event2_head *)mapping; event = (struct tcg_pcr_event2_head *)mapping;
/*
* The loop below will unmap these fields if the log is larger than
* one page, so save them here for reference:
*/
count = READ_ONCE(event->count);
event_type = READ_ONCE(event->event_type);
efispecid = (struct tcg_efi_specid_event_head *)event_header->event; efispecid = (struct tcg_efi_specid_event_head *)event_header->event;
/* Check if event is malformed. */ /* Check if event is malformed. */
if (event->count > efispecid->num_algs) { if (count > efispecid->num_algs) {
size = 0; size = 0;
goto out; goto out;
} }
for (i = 0; i < event->count; i++) { for (i = 0; i < count; i++) {
halg_size = sizeof(event->digests[i].alg_id); halg_size = sizeof(event->digests[i].alg_id);
/* Map the digest's algorithm identifier */ /* Map the digest's algorithm identifier */
...@@ -256,8 +263,9 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event, ...@@ -256,8 +263,9 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
+ event_field->event_size; + event_field->event_size;
size = marker - marker_start; size = marker - marker_start;
if ((event->event_type == 0) && (event_field->event_size == 0)) if (event_type == 0 && event_field->event_size == 0)
size = 0; size = 0;
out: out:
if (do_mapping) if (do_mapping)
TPM_MEMUNMAP(mapping, mapping_size); TPM_MEMUNMAP(mapping, mapping_size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment