lkml.org 
[lkml]   [2022]   [Oct]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 6.0 08/32] of/fdt: Don't calculate initrd size from DT if start > end
    Date
    From: Marek Bykowski <marek.bykowski@gmail.com>

    [ Upstream commit d5e3050c0feb8bf7b9a75482fafcc31b90257926 ]

    If the properties 'linux,initrd-start' and 'linux,initrd-end' of
    the chosen node populated from the bootloader, eg. U-Boot, are so that
    start > end, then the phys_initrd_size calculated from end - start is
    negative that subsequently gets converted to a high positive value for
    being unsigned long long. Then, the memory region with the (invalid)
    size is added to the bootmem and attempted being paged in paging_init()
    that results in the kernel fault.

    For example, on the FVP ARM64 system I'm running, the U-Boot populates
    the 'linux,initrd-start' with 8800_0000 and 'linux,initrd-end' with 0.
    The phys_initrd_size calculated is then ffff_ffff_7800_0000
    (= 0 - 8800_0000 = -8800_0000 + ULLONG_MAX + 1). paging_init() then
    attempts to map the address 8800_0000 + ffff_ffff_7800_0000 and oops'es
    as below.

    It should be stressed, it is generally a fault of the bootloader's with
    the kernel relying on it, however we should not allow the bootloader's
    misconfiguration to lead to the kernel oops. Not only the kernel should be
    bullet proof against it but also finding the root cause of the paging
    fault spanning over the bootloader, DT, and kernel may happen is not so
    easy.

    Unable to handle kernel paging request at virtual address fffffffefe43c000
    Mem abort info:
    ESR = 0x96000007
    EC = 0x25: DABT (current EL), IL = 32 bits
    SET = 0, FnV = 0
    EA = 0, S1PTW = 0
    Data abort info:
    ISV = 0, ISS = 0x00000007
    CM = 0, WnR = 0
    swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000080e3d000
    [fffffffefe43c000] pgd=0000000080de9003, pud=0000000080de9003
    Unable to handle kernel paging request at virtual address ffffff8000de9f90
    Mem abort info:
    ESR = 0x96000005
    EC = 0x25: DABT (current EL), IL = 32 bits
    SET = 0, FnV = 0
    EA = 0, S1PTW = 0
    Data abort info:
    ISV = 0, ISS = 0x00000005
    CM = 0, WnR = 0
    swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000080e3d000
    [ffffff8000de9f90] pgd=0000000000000000, pud=0000000000000000
    Internal error: Oops: 96000005 [#1] PREEMPT SMP
    Modules linked in:
    CPU: 0 PID: 0 Comm: swapper Not tainted 5.4.51-yocto-standard #1
    Hardware name: FVP Base (DT)
    pstate: 60000085 (nZCv daIf -PAN -UAO)
    pc : show_pte+0x12c/0x1b4
    lr : show_pte+0x100/0x1b4
    sp : ffffffc010ce3b30
    x29: ffffffc010ce3b30 x28: ffffffc010ceed80
    x27: fffffffefe43c000 x26: fffffffefe43a028
    x25: 0000000080bf0000 x24: 0000000000000025
    x23: ffffffc010b8d000 x22: ffffffc010e3d000
    x23: ffffffc010b8d000 x22: ffffffc010e3d000
    x21: 0000000080de9000 x20: ffffff7f80000f90
    x19: fffffffefe43c000 x18: 0000000000000030
    x17: 0000000000001400 x16: 0000000000001c00
    x15: ffffffc010cef1b8 x14: ffffffffffffffff
    x13: ffffffc010df1f40 x12: ffffffc010df1b70
    x11: ffffffc010ce3b30 x10: ffffffc010ce3b30
    x9 : 00000000ffffffc8 x8 : 0000000000000000
    x7 : 000000000000000f x6 : ffffffc010df16e8
    x5 : 0000000000000000 x4 : 0000000000000000
    x3 : 00000000ffffffff x2 : 0000000000000000
    x1 : 0000008080000000 x0 : ffffffc010af1d68
    Call trace:
    show_pte+0x12c/0x1b4
    die_kernel_fault+0x54/0x78
    __do_kernel_fault+0x11c/0x128
    do_translation_fault+0x58/0xac
    do_mem_abort+0x50/0xb0
    el1_da+0x1c/0x90
    __create_pgd_mapping+0x348/0x598
    paging_init+0x3f0/0x70d0
    setup_arch+0x2c0/0x5d4
    start_kernel+0x94/0x49c
    Code: 92748eb5 900052a0 9135a000 cb010294 (f8756a96) 

    Signed-off-by: Marek Bykowski <marek.bykowski@gmail.com>
    Link: https://lore.kernel.org/r/20220909023358.76881-1-marek.bykowski@gmail.com
    Signed-off-by: Rob Herring <robh@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/of/fdt.c | 2 ++
    1 file changed, 2 insertions(+)

    diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
    index 1c573e7a60bc..f2c660a137be 100644
    --- a/drivers/of/fdt.c
    +++ b/drivers/of/fdt.c
    @@ -936,6 +936,8 @@ static void __init early_init_dt_check_for_initrd(unsigned long node)
    if (!prop)
    return;
    end = of_read_number(prop, len/4);
    + if (start > end)
    + return;

    __early_init_dt_declare_initrd(start, end);
    phys_initrd_start = start;
    --
    2.35.1
    \
     
     \ /
      Last update: 2022-10-18 02:09    [W:4.616 / U:0.128 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site