Message ID | 20240221-arm32-lpae-pan-v2-0-991096bba5d8@linaro.org (mailing list archive) |
---|---|
Headers | show |
Series | PAN for ARM32 using LPAE | expand |
On Wed, Feb 21, 2024 at 12:04 AM Linus Walleij <linus.walleij@linaro.org> wrote: > This is a patch set from Catalin that ended up on the back burner. > > Since LPAE systems, i.e. ARM32 systems with a lot of physical memory, > will be with us for a while more, this is a pretty straight-forward > hardening measure that we should support. > > The last patch explains the mechanism: since PAN using CPU domains > isn't available when using the LPAE MMU tables, we use the split > between the two translation base tables instead: TTBR0 is for > userspace pages and TTBR1 is for kernelspace tables. When executing > in kernelspace: we protect userspace by simply disabling page > walks in TTBR0. I'll put the modified v2 (minor fixes mentioned on the patches) into Russell's patch tracker as there are no more comments. Yours, Linus Walleij
This is a patch set from Catalin that ended up on the back burner. Since LPAE systems, i.e. ARM32 systems with a lot of physical memory, will be with us for a while more, this is a pretty straight-forward hardening measure that we should support. The last patch explains the mechanism: since PAN using CPU domains isn't available when using the LPAE MMU tables, we use the split between the two translation base tables instead: TTBR0 is for userspace pages and TTBR1 is for kernelspace tables. When executing in kernelspace: we protect userspace by simply disabling page walks in TTBR0. The simplest way to test a PAN crash: - Enable CONFIG_LKDTM - echo "ACCESS_USERSPACE" | cat >/sys/kernel/debug/provoke-crash/DIRECT - echo "EXEC_USERSPACE" | cat >/sys/kernel/debug/provoke-crash/DIRECT This was also tested by a simple hack in the ELF loader: create_elf_tables() + unsigned char *test; (...) if (copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes))) return -EFAULT; + /* Cause a kernelspace access to userspace memory */ + test = (char *)u_rand_bytes; + pr_info("Some byte: %02x\n", *test); This tries to read a byte from userspace memory right after the first unconditional copy_to_user(), a function that carefully switches access permissions if we're using PAN. Without LPAE PAN this will just happily print these bytes from userspace but with LPAE PAN it will cause a predictable crash: Run /init as init process Some byte: ac 8<--- cut here --- Unable to handle kernel paging request at virtual address 7ec59f6b when read [7ec59f6b] *pgd=82c3b003, *pmd=82863003, *pte=e00000882f6f5f Internal error: Oops: 206 [#1] SMP ARM CPU: 0 PID: 47 Comm: rc.init Not tainted 6.7.0-rc1+ #25 Hardware name: ARM-Versatile Express PC is at create_elf_tables+0x13c/0x608 Thus we can show that LPAE PAN does its job. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- Changes in v1 (from Catalins original patch set): - Use IS_ENABLED() to avoid some ifdefs Changes in v2: - Make the TTBCR a separate field in struct svc_pt_regs as requested by Russell. Adjust code accordingly. - Push the MM page fault permission check into a local function and avoid the too generic uaccess_disabled() as requested by Ard. - Link to v1: https://lore.kernel.org/r/20240123-arm32-lpae-pan-v1-0-7ea98a20514c@linaro.org --- Catalin Marinas (4): ARM: Add TTBCR_* definitions to pgtable-3level-hwdef.h ARM: Move asm statements accessing TTBCR into C functions ARM: Reduce the number of #ifdef CONFIG_CPU_SW_DOMAIN_PAN ARM: Implement privileged no-access using TTBR0 page table walks disabling arch/arm/Kconfig | 22 +++++++++-- arch/arm/include/asm/assembler.h | 1 + arch/arm/include/asm/pgtable-3level-hwdef.h | 26 +++++++++++++ arch/arm/include/asm/proc-fns.h | 12 ++++++ arch/arm/include/asm/ptrace.h | 1 + arch/arm/include/asm/uaccess-asm.h | 58 +++++++++++++++++++++++++++-- arch/arm/include/asm/uaccess.h | 51 ++++++++++++++++++++++--- arch/arm/kernel/asm-offsets.c | 1 + arch/arm/kernel/suspend.c | 8 ++++ arch/arm/lib/csumpartialcopyuser.S | 20 +++++++++- arch/arm/mm/fault.c | 29 +++++++++++++++ arch/arm/mm/mmu.c | 7 ++-- 12 files changed, 218 insertions(+), 18 deletions(-) --- base-commit: 6613476e225e090cc9aad49be7fa504e290dd33d change-id: 20231216-arm32-lpae-pan-56125ab63d63 Best regards,