mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
huge_ptep_get() can be handed a virtual address pointing to the middle
of a contpmd/contpte mapped hugetlb folio (examples of callers are
pagemap_hugetlb_range, page_mapped_in_vma).
The arm64 helper rewalks the pgtables in find_num_contig to answer
whether the huge pte we have maps a contpmd or a contpte hugetlb folio,
and returns CONT_PMDS or CONT_PTES, so that it can collect a/d bits over
the contiguous ptes. We can falsely return CONT_PTES instead of
CONT_PMDS if the addr is not aligned. On systems where CONT_PTES !=
CONT_PMDS (meaning page size is 16K), we could collect excess A/D bit
state, meaning extra work for the kernel. Even worse, we may iterate
beyond the PTE table and dereference a garbage ptep pointer to access
physical memory we don't own. Since the ptep pointer is a linear map
address, we may run off the end of the linear map or into a hole,
dereference a VA not mapped into the kernel pgtables and cause kernel
panic.
Fix this by aligning the pmdp pointer down to a contpmd base before
checking equality with the passed huge pte pointer, to correctly answer
whether the huge pte is the base of a contpmd block.
Fixes:
|
||
|---|---|---|
| .. | ||
| cache.S | ||
| context.c | ||
| contpte.c | ||
| copypage.c | ||
| dma-mapping.c | ||
| extable.c | ||
| fault.c | ||
| fixmap.c | ||
| flush.c | ||
| gcs.c | ||
| hugetlbpage.c | ||
| init.c | ||
| ioremap.c | ||
| kasan_init.c | ||
| Makefile | ||
| mem_encrypt.c | ||
| mmap.c | ||
| mmu.c | ||
| mteswap.c | ||
| pageattr.c | ||
| pgd.c | ||
| physaddr.c | ||
| proc.S | ||
| ptdump_debugfs.c | ||
| ptdump.c | ||
| trans_pgd-asm.S | ||
| trans_pgd.c | ||