diff options
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/efi/efi-bgrt.c | 26 | ||||
-rw-r--r-- | drivers/firmware/google/vpd.c | 8 |
2 files changed, 29 insertions, 5 deletions
diff --git a/drivers/firmware/efi/efi-bgrt.c b/drivers/firmware/efi/efi-bgrt.c index 8bf27323f7a3..b58233e4ed71 100644 --- a/drivers/firmware/efi/efi-bgrt.c +++ b/drivers/firmware/efi/efi-bgrt.c @@ -27,6 +27,26 @@ struct bmp_header { u32 size; } __packed; +static bool efi_bgrt_addr_valid(u64 addr) +{ + efi_memory_desc_t *md; + + for_each_efi_memory_desc(md) { + u64 size; + u64 end; + + if (md->type != EFI_BOOT_SERVICES_DATA) + continue; + + size = md->num_pages << EFI_PAGE_SHIFT; + end = md->phys_addr + size; + if (addr >= md->phys_addr && addr < end) + return true; + } + + return false; +} + void __init efi_bgrt_init(struct acpi_table_header *table) { void *image; @@ -36,7 +56,7 @@ void __init efi_bgrt_init(struct acpi_table_header *table) if (acpi_disabled) return; - if (!efi_enabled(EFI_BOOT)) + if (!efi_enabled(EFI_MEMMAP)) return; if (table->length < sizeof(bgrt_tab)) { @@ -65,6 +85,10 @@ void __init efi_bgrt_init(struct acpi_table_header *table) goto out; } + if (!efi_bgrt_addr_valid(bgrt->image_address)) { + pr_notice("Ignoring BGRT: invalid image address\n"); + goto out; + } image = early_memremap(bgrt->image_address, sizeof(bmp_header)); if (!image) { pr_notice("Ignoring BGRT: failed to map image header memory\n"); diff --git a/drivers/firmware/google/vpd.c b/drivers/firmware/google/vpd.c index 1e7860f02f4f..31058d400bda 100644 --- a/drivers/firmware/google/vpd.c +++ b/drivers/firmware/google/vpd.c @@ -136,12 +136,12 @@ static int vpd_section_attrib_add(const u8 *key, s32 key_len, info->value = value; INIT_LIST_HEAD(&info->list); - list_add_tail(&info->list, &sec->attribs); ret = sysfs_create_bin_file(sec->kobj, &info->bin_attr); if (ret) goto free_info_key; + list_add_tail(&info->list, &sec->attribs); return 0; free_info_key: @@ -158,8 +158,8 @@ static void vpd_section_attrib_destroy(struct vpd_section *sec) struct vpd_attrib_info *temp; list_for_each_entry_safe(info, temp, &sec->attribs, list) { - kfree(info->key); sysfs_remove_bin_file(sec->kobj, &info->bin_attr); + kfree(info->key); kfree(info); } } @@ -244,7 +244,7 @@ static int vpd_section_destroy(struct vpd_section *sec) { if (sec->enabled) { vpd_section_attrib_destroy(sec); - kobject_del(sec->kobj); + kobject_put(sec->kobj); sysfs_remove_bin_file(vpd_kobj, &sec->bin_attr); kfree(sec->raw_name); iounmap(sec->baseaddr); @@ -331,7 +331,7 @@ static void __exit vpd_platform_exit(void) { vpd_section_destroy(&ro_vpd); vpd_section_destroy(&rw_vpd); - kobject_del(vpd_kobj); + kobject_put(vpd_kobj); } module_init(vpd_platform_init); |