From: Suzuki.Poulose@arm•com (Suzuki K. Poulose)
To: linux-arm-kernel@lists•infradead.org
Subject: [PATCH v2 6/6] arm64: kernel: Add support for Privileged Access Never
Date: Tue, 21 Jul 2015 11:30:08 +0100 [thread overview]
Message-ID: <55AE1F30.6020803@arm.com> (raw)
In-Reply-To: <1437154221-5736-7-git-send-email-james.morse@arm.com>
On 17/07/15 18:30, James Morse wrote:
> 'Privileged Access Never' is a new arm8.1 feature which prevents
> privileged code from accessing any virtual address where read or write
> access is also permitted at EL0.
>
> This patch enables the PAN feature on all CPUs, and modifies {get,put}_user
> helpers temporarily to permit access.
>
> This will catch kernel bugs where user memory is accessed directly.
> 'Unprivileged loads and stores' using ldtrb et al are unaffected by PAN.
>
> Signed-off-by: James Morse <james.morse@arm•com>
> Cc: Catalin Marinas <catalin.marinas@arm•com>
> Cc: Will Deacon <will.deacon@arm•com>
> ---
> arch/arm64/Kconfig | 14 ++++++++++++++
> arch/arm64/include/asm/cpufeature.h | 3 ++-
> arch/arm64/include/asm/futex.h | 8 ++++++++
> arch/arm64/include/asm/processor.h | 2 ++
> arch/arm64/include/asm/sysreg.h | 9 +++++++++
> arch/arm64/include/asm/uaccess.h | 11 +++++++++++
> arch/arm64/include/uapi/asm/ptrace.h | 1 +
> arch/arm64/kernel/cpufeature.c | 20 ++++++++++++++++++++
> arch/arm64/lib/clear_user.S | 8 ++++++++
> arch/arm64/lib/copy_from_user.S | 8 ++++++++
> arch/arm64/lib/copy_in_user.S | 8 ++++++++
> arch/arm64/lib/copy_to_user.S | 8 ++++++++
> arch/arm64/mm/fault.c | 23 +++++++++++++++++++++++
> 13 files changed, 122 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 318175f62c24..c53a4b1d5968 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -597,6 +597,20 @@ config FORCE_MAX_ZONEORDER
> default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
> default "11"
>
> +config ARM64_PAN
> + bool "Enable support for Privileged Access Never (PAN)"
> + default y
> + help
> + Privileged Access Never (PAN; part of the ARMv8.1 Extensions)
> + prevents the kernel or hypervisor from accessing user-space (EL0)
> + memory directly.
> +
> + Choosing this option will cause any unprotected (not using
> + copy_to_user et al) memory access to fail with a permission fault.
> +
> + The feature is detected at runtime, and will remain as a 'nop'
> + instruction if the cpu does not implement the feature.
> +
> menuconfig ARMV8_DEPRECATED
> bool "Emulate deprecated/obsolete ARMv8 instructions"
> depends on COMPAT
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index ef38e21ed719..420329a1b98f 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -25,8 +25,9 @@
> #define ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE 1
> #define ARM64_WORKAROUND_845719 2
> #define ARM64_HAS_SYSREG_GIC_CPUIF 3
> +#define ARM64_HAS_PAN 4
>
> -#define ARM64_NCAPS 4
> +#define ARM64_NCAPS 5
>
> #ifndef __ASSEMBLY__
>
> diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h
> index 74069b3bd919..775e85b9d1f2 100644
> --- a/arch/arm64/include/asm/futex.h
> +++ b/arch/arm64/include/asm/futex.h
> @@ -20,10 +20,16 @@
>
> #include <linux/futex.h>
> #include <linux/uaccess.h>
> +
> +#include <asm/alternative.h>
> +#include <asm/cpufeature.h>
> #include <asm/errno.h>
> +#include <asm/sysreg.h>
>
> #define __futex_atomic_op(insn, ret, oldval, uaddr, tmp, oparg) \
> asm volatile( \
> + ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, \
> + CONFIG_ARM64_PAN) \
> "1: ldxr %w1, %2\n" \
> insn "\n" \
> "2: stlxr %w3, %w0, %2\n" \
> @@ -39,6 +45,8 @@
> " .align 3\n" \
> " .quad 1b, 4b, 2b, 4b\n" \
> " .popsection\n" \
> + ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, \
> + CONFIG_ARM64_PAN) \
> : "=&r" (ret), "=&r" (oldval), "+Q" (*uaddr), "=&r" (tmp) \
> : "r" (oparg), "Ir" (-EFAULT) \
> : "memory")
> diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
> index e4c893e54f01..98f32355dc97 100644
> --- a/arch/arm64/include/asm/processor.h
> +++ b/arch/arm64/include/asm/processor.h
> @@ -186,4 +186,6 @@ static inline void spin_lock_prefetch(const void *x)
>
> #endif
>
> +void cpu_enable_pan(void);
> +
> #endif /* __ASM_PROCESSOR_H */
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 56391fbae1e1..f243bb1adaa5 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -20,12 +20,21 @@
> #ifndef __ASM_SYSREG_H
> #define __ASM_SYSREG_H
>
> +#include <asm/opcodes.h>
> +
> #define SCTLR_EL1_CP15BEN (0x1 << 5)
> #define SCTLR_EL1_SED (0x1 << 8)
>
> #define sys_reg(op0, op1, crn, crm, op2) \
> ((((op0)-2)<<19)|((op1)<<16)|((crn)<<12)|((crm)<<8)|((op2)<<5))
>
> +#define REG_PSTATE_PAN_IMM sys_reg(2, 0, 4, 0, 4)
I think the above encoding is incorrect (even though, the code works fine).
While setting the PAN with an immediate value, the PAN is treated just like
a Process state field and the encoding becomes:
Op0=0, Op1=0 ...
The encoding 2,0 ,... works fine in this case due to a bug in the sys_reg()
macro above, where op0 is encoded as (op0 - 2). I took a look at the ARMv8 ARM,
section C5.2.{3, 4, 5, 6} and the system instruction class reserves bits[20-19] for Op0.
I think we should fix that first and use the appropriate encoding mandated by the
architecture to avoid further errors.
> +#define PSTATE_PAN (1 << 22)
> +#define SCTLR_EL1_SPAN (1 << 23)
> +
> +#define SET_PSTATE_PAN(x) __inst_arm(0xd5000000 | REG_PSTATE_PAN_IMM |\
> + (!!x)<<8 | 0x1f)
Thanks
Suzuki
next prev parent reply other threads:[~2015-07-21 10:30 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-17 17:30 [PATCH v2 0/6] arm64: kernel: Add support for Privileged Access Never James Morse
2015-07-17 17:30 ` [PATCH v2 1/6] arm64: kernel: Add cpuid_feature_extract_field() for 4bit sign extension James Morse
2015-07-20 11:32 ` Catalin Marinas
2015-07-20 13:20 ` Catalin Marinas
2015-07-17 17:30 ` [PATCH v2 2/6] arm64: kernel: preparatory: Move config_sctlr_el1 James Morse
2015-07-17 17:30 ` [PATCH v2 3/6] arm64: kernel: Add cpufeature 'enable' callback James Morse
2015-07-17 17:30 ` [PATCH v2 4/6] arm64: kernel: Add min_register_value and use '>=' for feature detection James Morse
2015-07-20 13:53 ` Catalin Marinas
2015-07-17 17:30 ` [PATCH v2 5/6] arm64: kernel: Add optional CONFIG_ parameter to ALTERNATIVE() James Morse
2015-07-17 17:30 ` [PATCH v2 6/6] arm64: kernel: Add support for Privileged Access Never James Morse
2015-07-20 14:01 ` Catalin Marinas
2015-07-21 10:30 ` Suzuki K. Poulose [this message]
2015-07-21 11:37 ` Catalin Marinas
2015-07-22 9:54 ` [PATCH] arm64: sys_reg() : Fix encoding of system registers Suzuki K. Poulose
2015-07-22 10:07 ` Catalin Marinas
2015-07-22 10:20 ` Suzuki K. Poulose
2015-07-22 10:38 ` [PATCH] arm64: Generalise msr_s/mrs_s operations Suzuki K. Poulose
2015-07-20 11:02 ` [PATCH v2 0/6] arm64: kernel: Add support for Privileged Access Never Vladimir Murzin
2015-07-20 11:17 ` Catalin Marinas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=55AE1F30.6020803@arm.com \
--to=suzuki.poulose@arm$(echo .)com \
--cc=linux-arm-kernel@lists$(echo .)infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox