Skip to content

Commit 04a8481

Browse files
Ard Biesheuvelwildea01
authored andcommitted
arm64: mm: avoid fdt_check_header() before the FDT is fully mapped
As reported by Zijun, the fdt_check_header() call in __fixmap_remap_fdt() is not safe since it is not guaranteed that the FDT header is mapped completely. Due to the minimum alignment of 8 bytes, the only fields we can assume to be mapped are 'magic' and 'totalsize'. Since the OF layer is in charge of validating the FDT image, and we are only interested in making reasonably sure that the size field contains a meaningful value, replace the fdt_check_header() call with an explicit comparison of the magic field's value against the expected value. Cc: <stable@vger.kernel.org> Reported-by: Zijun Hu <zijun_hu@htc.com> Acked-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Will Deacon <will.deacon@arm.com>
1 parent 3146bc6 commit 04a8481

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

arch/arm64/mm/mmu.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -686,9 +686,9 @@ void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
686686
/*
687687
* Check whether the physical FDT address is set and meets the minimum
688688
* alignment requirement. Since we are relying on MIN_FDT_ALIGN to be
689-
* at least 8 bytes so that we can always access the size field of the
690-
* FDT header after mapping the first chunk, double check here if that
691-
* is indeed the case.
689+
* at least 8 bytes so that we can always access the magic and size
690+
* fields of the FDT header after mapping the first chunk, double check
691+
* here if that is indeed the case.
692692
*/
693693
BUILD_BUG_ON(MIN_FDT_ALIGN < 8);
694694
if (!dt_phys || dt_phys % MIN_FDT_ALIGN)
@@ -716,7 +716,7 @@ void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
716716
create_mapping_noalloc(round_down(dt_phys, SWAPPER_BLOCK_SIZE),
717717
dt_virt_base, SWAPPER_BLOCK_SIZE, prot);
718718

719-
if (fdt_check_header(dt_virt) != 0)
719+
if (fdt_magic(dt_virt) != FDT_MAGIC)
720720
return NULL;
721721

722722
*size = fdt_totalsize(dt_virt);

0 commit comments

Comments
 (0)