[PATCH v2 2/3] arm64: mm: Handle PAN faults on uaccess CPY* instructions
Robin Murphy
robin.murphy at arm.com
Thu Mar 6 07:28:26 PST 2025
On 28/02/2025 5:00 pm, Kristina Martšenko wrote:
> A subsequent patch will use CPY* instructions to copy between user and
> kernel memory. Add handling for PAN faults caused by an intended kernel
> memory access erroneously accessing user memory, in order to make it
> easier to debug kernel bugs and to keep the same behavior as with
> regular loads/stores.
I'd be tempted to fold the search_exception_tables() call into
insn_may_access_user() itself, but either way,
Reviewed-by: Robin Murphy <robin.murphy at arm.com>
> Signed-off-by: Kristina Martšenko <kristina.martsenko at arm.com>
> ---
> arch/arm64/include/asm/extable.h | 3 +++
> arch/arm64/mm/extable.c | 11 +++++++++++
> arch/arm64/mm/fault.c | 4 +++-
> 3 files changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/extable.h b/arch/arm64/include/asm/extable.h
> index 5892b8977710..0a8cb2015c97 100644
> --- a/arch/arm64/include/asm/extable.h
> +++ b/arch/arm64/include/asm/extable.h
> @@ -33,6 +33,9 @@ do { \
> (b)->data = (tmp).data; \
> } while (0)
>
> +bool extable_insn_may_access_user(const struct exception_table_entry *ex,
> + unsigned long esr);
> +
> #ifdef CONFIG_BPF_JIT
> bool ex_handler_bpf(const struct exception_table_entry *ex,
> struct pt_regs *regs);
> diff --git a/arch/arm64/mm/extable.c b/arch/arm64/mm/extable.c
> index afb5241e4d91..f137596dda88 100644
> --- a/arch/arm64/mm/extable.c
> +++ b/arch/arm64/mm/extable.c
> @@ -20,6 +20,17 @@ static bool cpy_faulted_on_uaccess(const struct exception_table_entry *ex,
> return uaccess_is_write == fault_on_write;
> }
>
> +bool extable_insn_may_access_user(const struct exception_table_entry *ex,
> + unsigned long esr)
> +{
> + switch (ex->type) {
> + case EX_TYPE_UACCESS_CPY:
> + return cpy_faulted_on_uaccess(ex, esr);
> + default:
> + return true;
> + }
> +}
> +
> static inline unsigned long
> get_ex_fixup(const struct exception_table_entry *ex)
> {
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index da4854fc6150..c2f14f9c2d92 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -553,6 +553,7 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
> unsigned int mm_flags = FAULT_FLAG_DEFAULT;
> unsigned long addr = untagged_addr(far);
> struct vm_area_struct *vma;
> + const struct exception_table_entry *ex;
> int si_code;
> int pkey = -1;
>
> @@ -606,7 +607,8 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
> die_kernel_fault("execution of user memory",
> addr, esr, regs);
>
> - if (!search_exception_tables(regs->pc))
> + ex = search_exception_tables(regs->pc);
> + if (!ex || !extable_insn_may_access_user(ex, esr))
> die_kernel_fault("access to user memory outside uaccess routines",
> addr, esr, regs);
> }
More information about the linux-arm-kernel
mailing list