Messages in this thread Patch in this message | | | From | Ross Philipson <> | Subject | [PATCH 1/2] x86: Check return values from early_memremap calls | Date | Fri, 15 Apr 2022 11:10:00 -0400 |
| |
There are a number of places where early_memremap is called but the return pointer is not checked for NULL. The call can result in a NULL being returned so the checks must be added.
Signed-off-by: Ross Philipson <ross.philipson@oracle.com> --- arch/x86/kernel/devicetree.c | 10 ++++++++++ arch/x86/kernel/e820.c | 5 +++++ arch/x86/kernel/jailhouse.c | 6 ++++++ arch/x86/kernel/mpparse.c | 23 +++++++++++++++++++++++ arch/x86/kernel/setup.c | 5 +++++ arch/x86/xen/enlighten_hvm.c | 2 ++ arch/x86/xen/mmu_pv.c | 8 ++++++++ arch/x86/xen/setup.c | 2 ++ 8 files changed, 61 insertions(+)
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index 5cd51f2..ca23875 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c @@ -292,10 +292,20 @@ static void __init x86_flattree_get_config(void) map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128); dt = early_memremap(initial_dtb, map_len); + if (!dt) { + pr_warn("devicetree: failed to memremap initial dtb\n"); + return; + } + size = fdt_totalsize(dt); if (map_len < size) { early_memunmap(dt, map_len); dt = early_memremap(initial_dtb, size); + if (!dt) { + pr_warn("devicetree: failed to memremap initial dtb\n"); + return; + } + map_len = size; } diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index f267205..f90b883 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -728,6 +728,11 @@ void __init e820__memory_setup_extended(u64 phys_addr, u32 data_len) struct setup_data *sdata; sdata = early_memremap(phys_addr, data_len); + if (!sdata) { + pr_warn("e820: failed to memremap extended\n"); + return; + } + entries = sdata->len / sizeof(*extmap); extmap = (struct boot_e820_entry *)(sdata->data); diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index 4eb8f2d..80db0c2 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -221,6 +221,9 @@ static void __init jailhouse_init_platform(void) while (pa_data) { mapping = early_memremap(pa_data, sizeof(header)); + if (!mapping) + panic("Jailhouse: failed to memremap setup_data header\n"); + memcpy(&header, mapping, sizeof(header)); early_memunmap(mapping, sizeof(header)); @@ -241,6 +244,9 @@ static void __init jailhouse_init_platform(void) setup_data_len = min_t(unsigned long, sizeof(setup_data), (unsigned long)header.len); mapping = early_memremap(pa_data, setup_data_len); + if (!mapping) + panic("Jailhouse: failed to memremap setup_data\n"); + memcpy(&setup_data, mapping, setup_data_len); early_memunmap(mapping, setup_data_len); diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index fed721f..8bac042 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -424,6 +424,9 @@ static unsigned long __init get_mpc_size(unsigned long physptr) unsigned long size; mpc = early_memremap(physptr, PAGE_SIZE); + if (!mpc) + return 0; + size = mpc->length; early_memunmap(mpc, PAGE_SIZE); apic_printk(APIC_VERBOSE, " mpc: %lx-%lx\n", physptr, physptr + size); @@ -437,7 +440,16 @@ static int __init check_physptr(struct mpf_intel *mpf, unsigned int early) unsigned long size; size = get_mpc_size(mpf->physptr); + if (!size) { + pr_err("MPTABLE: error getting MP table size\n"); + return -1; + } + mpc = early_memremap(mpf->physptr, size); + if (!mpc) { + pr_err("MPTABLE: error mapping MP table physptr\n"); + return -1; + } /* * Read the physical hardware table. Anything here will @@ -552,6 +564,7 @@ void __init default_get_smp_config(unsigned int early) static void __init smp_reserve_memory(struct mpf_intel *mpf) { + /* If get_mpc_size() is 0, memblock_reserve() will just do nothing */ memblock_reserve(mpf->physptr, get_mpc_size(mpf->physptr)); } @@ -567,6 +580,11 @@ static int __init smp_scan_config(unsigned long base, unsigned long length) while (length > 0) { bp = early_memremap(base, length); + if (!bp) { + pr_err("MPTABLE: error mapping SMP config\n"); + return 0; + } + mpf = (struct mpf_intel *)bp; if ((*bp == SMP_MAGIC_IDENT) && (mpf->length == 1) && @@ -864,6 +882,11 @@ static int __init update_mp_table(void) goto do_unmap_mpf; size = get_mpc_size(mpf->physptr); + if (!size) { + pr_err("MPTABLE: error getting MP table size\n"); + goto do_unmap_mpf; + } + mpc = early_memremap(mpf->physptr, size); if (!mpc) { pr_err("MPTABLE: mpc early_memremap() failed\n"); diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index c95b9ac..824e901 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -345,6 +345,11 @@ static void __init parse_setup_data(void) u32 data_len, data_type; data = early_memremap(pa_data, sizeof(*data)); + if (!data) { + pr_warn("setup: failed to memremap in parse_setup_data\n"); + return; + } + data_len = data->len + sizeof(struct setup_data); data_type = data->type; pa_next = data->next; diff --git a/arch/x86/xen/enlighten_hvm.c b/arch/x86/xen/enlighten_hvm.c index 517a9d8..6182c5b 100644 --- a/arch/x86/xen/enlighten_hvm.c +++ b/arch/x86/xen/enlighten_hvm.c @@ -64,6 +64,8 @@ static void __init reserve_shared_info(void) memblock_reserve(pa, PAGE_SIZE); HYPERVISOR_shared_info = early_memremap(pa, PAGE_SIZE); + if (!HYPERVISOR_shared_info) + panic("xen: failed to memmap hypervisor shared page: 0x%llx\n", pa); } static void __init xen_hvm_init_mem_mapping(void) diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c index 0035486..2aff5c6 100644 --- a/arch/x86/xen/mmu_pv.c +++ b/arch/x86/xen/mmu_pv.c @@ -1823,6 +1823,8 @@ static unsigned long __init xen_read_phys_ulong(phys_addr_t addr) unsigned long val; vaddr = early_memremap_ro(addr, sizeof(val)); + if (!vaddr) + panic("xen: failed to memmap physical address: 0x%llx\n", addr); val = *vaddr; early_memunmap(vaddr, sizeof(val)); return val; @@ -1918,14 +1920,20 @@ void __init xen_relocate_p2m(void) new_p2m = (unsigned long *)(2 * PGDIR_SIZE); for (idx_pud = 0; idx_pud < n_pud; idx_pud++) { pud = early_memremap(pud_phys, PAGE_SIZE); + if (!pud) + panic("xen: failed to memmap PUD physical address: 0x%llx\n", pud_phys); clear_page(pud); for (idx_pmd = 0; idx_pmd < min(n_pmd, PTRS_PER_PUD); idx_pmd++) { pmd = early_memremap(pmd_phys, PAGE_SIZE); + if (!pmd) + panic("xen: failed to memmap PMD physical address: 0x%llx\n", pmd_phys); clear_page(pmd); for (idx_pt = 0; idx_pt < min(n_pt, PTRS_PER_PMD); idx_pt++) { pt = early_memremap(pt_phys, PAGE_SIZE); + if (!pt) + panic("xen: failed to memmap PT physical address: 0x%llx\n", pt_phys); clear_page(pt); for (idx_pte = 0; idx_pte < min(n_pte, PTRS_PER_PTE); diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 81aa46f..5e74496 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -685,6 +685,8 @@ static void __init xen_phys_memcpy(phys_addr_t dest, phys_addr_t src, len = min(dest_len, src_len); to = early_memremap(dest - dest_off, dest_len + dest_off); from = early_memremap(src - src_off, src_len + src_off); + if (!to || !from) + panic("xen: failed to memmap for physical address memcpy\n"); memcpy(to, from, len); early_memunmap(to, dest_len + dest_off); early_memunmap(from, src_len + src_off); -- 1.8.3.1
| |