[PATCH] arm64: mm: use u32 for FDT size in fixmap_remap_fdt()

Sang-Heon Jeon ekffu200098 at gmail.com
Fri May 15 06:55:45 PDT 2026


On Fri, May 15, 2026 at 2:13 AM Sang-Heon Jeon <ekffu200098 at gmail.com> wrote:
>
> fixmap_remap_fdt() uses a signed int for the FDT size, so a malformed
> totalsize bigger than INT_MAX wrongly passes the MAX_FDT_SIZE check.
> Then create_mapping_noalloc() is called with a huge size and triggers
> a BUG_ON() in the MMU code, with no diagnostic about the malformed FDT.
>
> Change the FDT size from int to u32, which is the return type of
> fdt_totalsize(). So a malformed totalsize no longer wrongly passes the
> MAX_FDT_SIZE check, and setup_machine_fdt() prints a pr_crit
> diagnostic for it, not a BUG_ON in the MMU code.
>
> Fixes: 61bd93ce801b ("arm64: use fixmap region for permanent FDT mapping")
> Signed-off-by: Sang-Heon Jeon <ekffu200098 at gmail.com>
> ---
>  arch/arm64/include/asm/mmu.h | 2 +-
>  arch/arm64/kernel/setup.c    | 4 ++--
>  arch/arm64/mm/fixmap.c       | 4 ++--
>  3 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
> index 5e1211c540ab..a6b388ef4c3f 100644
> --- a/arch/arm64/include/asm/mmu.h
> +++ b/arch/arm64/include/asm/mmu.h
> @@ -68,7 +68,7 @@ extern void create_mapping_noalloc(phys_addr_t phys, unsigned long virt,
>  extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
>                                unsigned long virt, phys_addr_t size,
>                                pgprot_t prot, bool page_mappings_only);
> -extern void *fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot);
> +extern void *fixmap_remap_fdt(phys_addr_t dt_phys, u32 *size, pgprot_t prot);
>  extern void mark_linear_text_alias_ro(void);
>  extern int split_kernel_leaf_mapping(unsigned long start, unsigned long end);
>  extern void linear_map_maybe_split_to_ptes(void);
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index 23c05dc7a8f2..7cabac0546dc 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -169,7 +169,7 @@ static void __init smp_build_mpidr_hash(void)
>
>  static void __init setup_machine_fdt(phys_addr_t dt_phys)
>  {
> -       int size = 0;
> +       u32 size = 0;
>         void *dt_virt = fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL);
>         const char *name;
>
> @@ -182,7 +182,7 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
>          */
>         if (!early_init_dt_scan(dt_virt, dt_phys)) {
>                 pr_crit("\n"
> -                       "Error: invalid device tree blob: PA=%pa, VA=%px, size=%d bytes\n"
> +                       "Error: invalid device tree blob: PA=%pa, VA=%px, size=%u bytes\n"
>                         "The dtb must be 8-byte aligned and must not exceed 2 MB in size.\n"
>                         "\nPlease check your bootloader.\n",
>                         &dt_phys, dt_virt, size);
> diff --git a/arch/arm64/mm/fixmap.c b/arch/arm64/mm/fixmap.c
> index c5c5425791da..c692e6ac2405 100644
> --- a/arch/arm64/mm/fixmap.c
> +++ b/arch/arm64/mm/fixmap.c
> @@ -134,11 +134,11 @@ void __set_fixmap(enum fixed_addresses idx,
>         }
>  }
>
> -void *__init fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
> +void *__init fixmap_remap_fdt(phys_addr_t dt_phys, u32 *size, pgprot_t prot)
>  {
>         const u64 dt_virt_base = __fix_to_virt(FIX_FDT);
>         phys_addr_t dt_phys_base;
> -       int offset;
> +       u32 offset;

Also sashiko found another issue with malformed total size. And I
think that can be resolved by the following changes.

        *size = fdt_totalsize(dt_virt);
  +     if (*size < sizeof(struct fdt_header))
  +             return NULL;

Before sending a separate patch about malformed totalsize. First, I'd
rather check reviewers' opinions.

1. Do we need to care about malformed totalsize? (including addressed
by the current patch)
2. Does the above change need to be merged with the current patch or not?

Looking forward to your feedback.

Best Regards,
Sang-Heon Jeon

>         void *dt_virt;
>
>         /*
> --
> 2.43.0
>



More information about the linux-arm-kernel mailing list