linux/arch
James Houghton c2134ed532 arm64: mm: Always make sw-dirty PTEs hw-dirty in pte_modify
commit 3c0696076a upstream.

It is currently possible for a userspace application to enter an
infinite page fault loop when using HugeTLB pages implemented with
contiguous PTEs when HAFDBS is not available. This happens because:

1. The kernel may sometimes write PTEs that are sw-dirty but hw-clean
   (PTE_DIRTY | PTE_RDONLY | PTE_WRITE).

2. If, during a write, the CPU uses a sw-dirty, hw-clean PTE in handling
   the memory access on a system without HAFDBS, we will get a page
   fault.

3. HugeTLB will check if it needs to update the dirty bits on the PTE.
   For contiguous PTEs, it will check to see if the pgprot bits need
   updating. In this case, HugeTLB wants to write a sequence of
   sw-dirty, hw-dirty PTEs, but it finds that all the PTEs it is about
   to overwrite are all pte_dirty() (pte_sw_dirty() => pte_dirty()),
   so it thinks no update is necessary.

We can get the kernel to write a sw-dirty, hw-clean PTE with the
following steps (showing the relevant VMA flags and pgprot bits):

i.   Create a valid, writable contiguous PTE.
       VMA vmflags:     VM_SHARED | VM_READ | VM_WRITE
       VMA pgprot bits: PTE_RDONLY | PTE_WRITE
       PTE pgprot bits: PTE_DIRTY | PTE_WRITE

ii.  mprotect the VMA to PROT_NONE.
       VMA vmflags:     VM_SHARED
       VMA pgprot bits: PTE_RDONLY
       PTE pgprot bits: PTE_DIRTY | PTE_RDONLY

iii. mprotect the VMA back to PROT_READ | PROT_WRITE.
       VMA vmflags:     VM_SHARED | VM_READ | VM_WRITE
       VMA pgprot bits: PTE_RDONLY | PTE_WRITE
       PTE pgprot bits: PTE_DIRTY | PTE_WRITE | PTE_RDONLY

Make it impossible to create a writeable sw-dirty, hw-clean PTE with
pte_modify(). Such a PTE should be impossible to create, and there may
be places that assume that pte_dirty() implies pte_hw_dirty().

Signed-off-by: James Houghton <jthoughton@google.com>
Fixes: 031e6e6b4e ("arm64: hugetlb: Avoid unnecessary clearing in huge_ptep_set_access_flags")
Cc: <stable@vger.kernel.org>
Acked-by: Will Deacon <will@kernel.org>
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Link: https://lore.kernel.org/r/20231204172646.2541916-3-jthoughton@google.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-12-20 15:17:41 +01:00
..
alpha alpha: remove __init annotation from exported page_is_ram() 2023-08-16 18:22:03 +02:00
arc memblock: allow to specify flags with memblock_add_node() 2023-12-20 15:17:33 +01:00
arm ARM: dts: imx28-xea: Pass the 'model' property 2023-12-13 18:36:41 +01:00
arm64 arm64: mm: Always make sw-dirty PTEs hw-dirty in pte_modify 2023-12-20 15:17:41 +01:00
csky kprobes: treewide: Cleanup the error messages for kprobes 2023-02-22 12:57:00 +01:00
h8300 h8300: Fix build errors from do_exit() to make_task_dead() transition 2023-02-01 08:27:21 +01:00
hexagon hexagon: Fix function name in die() 2023-02-01 08:27:20 +01:00
ia64 memblock: allow to specify flags with memblock_add_node() 2023-12-20 15:17:33 +01:00
m68k memblock: allow to specify flags with memblock_add_node() 2023-12-20 15:17:33 +01:00
microblaze exit: Add and use make_task_dead. 2023-02-01 08:27:20 +01:00
mips MIPS: Loongson64: Handle more memory types passed from firmware 2023-12-20 15:17:33 +01:00
nds32 exit: Add and use make_task_dead. 2023-02-01 08:27:20 +01:00
nios2 nios2: dts: Fix tse_mac "max-frame-size" property 2023-06-21 15:59:14 +02:00
openrisc openrisc: Properly store r31 to pt_regs on unhandled exceptions 2023-05-11 23:00:37 +09:00
parisc parisc: Drop the HP-UX ENOSYM and EREMOTERELEASE error codes 2023-12-08 08:48:02 +01:00
powerpc powerpc: Don't clobber f0/vs0 during fp|altivec register save 2023-12-08 08:48:01 +01:00
riscv riscv: fix misaligned access handling of C.SWSP and C.SDSP 2023-12-13 18:36:41 +01:00
s390 memblock: allow to specify flags with memblock_add_node() 2023-12-20 15:17:33 +01:00
sh sh: bios: Revive earlyprintk support 2023-11-20 11:08:23 +01:00
sparc sparc32: fix a braino in fault handling in csum_and_copy_..._user() 2023-11-08 17:26:42 +01:00
um um: Fix hostaudio build errors 2023-09-19 12:22:49 +02:00
x86 perf/x86/uncore: Don't WARN_ON_ONCE() for a broken discovery table 2023-12-20 15:17:32 +01:00
xtensa xtensa: boot/lib: fix function prototypes 2023-10-06 13:18:14 +02:00
.gitignore
Kconfig init: Provide arch_cpu_finalize_init() 2023-08-08 19:58:30 +02:00