[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen stable-4.8] xen/arm: Check if the FDT passed by the bootloader is valid



commit f6f543fee9be6c3ec0312c3ac2d931a23d407a52
Author:     Julien Grall <julien.grall@xxxxxxx>
AuthorDate: Thu Apr 20 16:12:27 2017 +0100
Commit:     Stefano Stabellini <sstabellini@xxxxxxxxxx>
CommitDate: Fri Jul 7 10:59:14 2017 -0700

    xen/arm: Check if the FDT passed by the bootloader is valid
    
    There is currently no sanity check on the FDT passed by the bootloader.
    Whilst they are stricly not necessary, it will avoid us to spend hours
    to try to find out why it does not work.
    
    >From the booting documentation for AArch32 [1] and AArch64 [2] must :
        - be placed on 8-byte boundary
        - not exceed 2MB (only on AArch64)
    
    Even if AArch32 does not seem to limit the size, Xen is not currently
    able to support more the 2MB FDT. It is better to crash rather with a nice
    error message than claiming we are supporting any size of FDT.
    
    The checks are mostly borrowed from the Linux code (see fixmap_remap_fdt
    in arch/arm64/mm/mmu.c).
    
    [1] Section 2 in linux/Documentation/arm64/booting.txt
    [2] Section 4b in linux/Documentation/arm/Booting
    
    Signed-off-by: Julien Grall <julien.grall@xxxxxxx>
    Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
    (cherry picked from commit 4a9d402746fd6fbd1f319eff29fa768f7d7aa62b)
---
 xen/arch/arm/mm.c           | 29 ++++++++++++++++++++++++++++-
 xen/arch/arm/setup.c        |  6 ++++++
 xen/include/asm-arm/setup.h |  3 +++
 3 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index f6d7555..a0c1e12 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -40,6 +40,8 @@
 #include <xsm/xsm.h>
 #include <xen/pfn.h>
 #include <xen/sizes.h>
+#include <xen/libfdt/libfdt.h>
+#include <asm/setup.h>
 
 struct domain *dom_xen, *dom_io, *dom_cow;
 
@@ -475,11 +477,36 @@ void * __init early_fdt_map(paddr_t fdt_paddr)
 {
     /* We are using 2MB superpage for mapping the FDT */
     paddr_t base_paddr = fdt_paddr & SECOND_MASK;
+    paddr_t offset;
+    void *fdt_virt;
+
+    /*
+     * Check whether the physical FDT address is set and meets the minimum
+     * alignment requirement. Since we are relying on MIN_FDT_ALIGN to be at
+     * least 8 bytes so that we always access the magic and size fields
+     * of the FDT header after mapping the first chunk, double check if
+     * that is indeed the case.
+     */
+    BUILD_BUG_ON(MIN_FDT_ALIGN < 8);
+    if ( !fdt_paddr || fdt_paddr % MIN_FDT_ALIGN )
+        return NULL;
+
+    /* The FDT is mapped using 2MB superpage */
+    BUILD_BUG_ON(BOOT_FDT_VIRT_START % SZ_2M);
 
     create_mappings(boot_second, BOOT_FDT_VIRT_START, paddr_to_pfn(base_paddr),
                     SZ_2M >> PAGE_SHIFT, SZ_2M);
 
-    return (void *)BOOT_FDT_VIRT_START + (fdt_paddr % SECOND_SIZE);
+    offset = fdt_paddr % SECOND_SIZE;
+    fdt_virt = (void *)BOOT_FDT_VIRT_START + offset;
+
+    if ( fdt_magic(fdt_virt) != FDT_MAGIC )
+        return NULL;
+
+    if ( fdt_totalsize(fdt_virt) > MAX_FDT_SIZE )
+        return NULL;
+
+    return fdt_virt;
 }
 
 void __init remove_early_mappings(void)
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 3a99ea8..f4e9605 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -733,6 +733,12 @@ void __init start_xen(unsigned long boot_phys_offset,
     smp_clear_cpu_maps();
 
     device_tree_flattened = early_fdt_map(fdt_paddr);
+    if ( !device_tree_flattened )
+        panic("Invalid device tree blob at physical address %#lx.\n"
+              "The DTB must be 8-byte aligned and must not exceed 2 MB in 
size.\n\n"
+              "Please check your bootloader.",
+              fdt_paddr);
+
     fdt_size = boot_fdt_info(device_tree_flattened, fdt_paddr);
 
     cmdline = boot_fdt_cmdline(device_tree_flattened);
diff --git a/xen/include/asm-arm/setup.h b/xen/include/asm-arm/setup.h
index 3da7a49..2efa6cb 100644
--- a/xen/include/asm-arm/setup.h
+++ b/xen/include/asm-arm/setup.h
@@ -3,6 +3,9 @@
 
 #include <public/version.h>
 
+#define MIN_FDT_ALIGN 8
+#define MAX_FDT_SIZE SZ_2M
+
 #define NR_MEM_BANKS 64
 
 #define MAX_MODULES 5 /* Current maximum useful modules */
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.8

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.