| From foo@baz Sun 27 Oct 2019 09:50:54 AM CET |
| From: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| Date: Thu, 24 Oct 2019 14:48:20 +0200 |
| Subject: arm64: fix SSBS sanitization |
| To: stable@vger.kernel.org |
| Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>, Will Deacon <will@kernel.org>, Catalin Marinas <catalin.marinas@arm.com>, Marc Zyngier <maz@kernel.org>, Mark Rutland <mark.rutland@arm.com>, Suzuki K Poulose <suzuki.poulose@arm.com>, Jeremy Linton <jeremy.linton@arm.com>, Andre Przywara <andre.przywara@arm.com>, Alexandru Elisei <alexandru.elisei@arm.com>, Will Deacon <will.deacon@arm.com> |
| Message-ID: <20191024124833.4158-36-ard.biesheuvel@linaro.org> |
| |
| From: Mark Rutland <mark.rutland@arm.com> |
| |
| [ Upstream commit f54dada8274643e3ff4436df0ea124aeedc43cae ] |
| |
| In valid_user_regs() we treat SSBS as a RES0 bit, and consequently it is |
| unexpectedly cleared when we restore a sigframe or fiddle with GPRs via |
| ptrace. |
| |
| This patch fixes valid_user_regs() to account for this, updating the |
| function to refer to the latest ARM ARM (ARM DDI 0487D.a). For AArch32 |
| tasks, SSBS appears in bit 23 of SPSR_EL1, matching its position in the |
| AArch32-native PSR format, and we don't need to translate it as we have |
| to for DIT. |
| |
| There are no other bit assignments that we need to account for today. |
| As the recent documentation describes the DIT bit, we can drop our |
| comment regarding DIT. |
| |
| While removing SSBS from the RES0 masks, existing inconsistent |
| whitespace is corrected. |
| |
| Fixes: d71be2b6c0e19180 ("arm64: cpufeature: Detect SSBS and advertise to userspace") |
| Signed-off-by: Mark Rutland <mark.rutland@arm.com> |
| Cc: Catalin Marinas <catalin.marinas@arm.com> |
| Cc: Suzuki K Poulose <suzuki.poulose@arm.com> |
| Cc: Will Deacon <will.deacon@arm.com> |
| Signed-off-by: Will Deacon <will.deacon@arm.com> |
| Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/arm64/kernel/ptrace.c | 15 ++++++++------- |
| 1 file changed, 8 insertions(+), 7 deletions(-) |
| |
| --- a/arch/arm64/kernel/ptrace.c |
| +++ b/arch/arm64/kernel/ptrace.c |
| @@ -1402,19 +1402,20 @@ asmlinkage void syscall_trace_exit(struc |
| } |
| |
| /* |
| - * SPSR_ELx bits which are always architecturally RES0 per ARM DDI 0487C.a |
| - * We also take into account DIT (bit 24), which is not yet documented, and |
| - * treat PAN and UAO as RES0 bits, as they are meaningless at EL0, and may be |
| - * allocated an EL0 meaning in future. |
| + * SPSR_ELx bits which are always architecturally RES0 per ARM DDI 0487D.a. |
| + * We permit userspace to set SSBS (AArch64 bit 12, AArch32 bit 23) which is |
| + * not described in ARM DDI 0487D.a. |
| + * We treat PAN and UAO as RES0 bits, as they are meaningless at EL0, and may |
| + * be allocated an EL0 meaning in future. |
| * Userspace cannot use these until they have an architectural meaning. |
| * Note that this follows the SPSR_ELx format, not the AArch32 PSR format. |
| * We also reserve IL for the kernel; SS is handled dynamically. |
| */ |
| #define SPSR_EL1_AARCH64_RES0_BITS \ |
| - (GENMASK_ULL(63,32) | GENMASK_ULL(27, 25) | GENMASK_ULL(23, 22) | \ |
| - GENMASK_ULL(20, 10) | GENMASK_ULL(5, 5)) |
| + (GENMASK_ULL(63, 32) | GENMASK_ULL(27, 25) | GENMASK_ULL(23, 22) | \ |
| + GENMASK_ULL(20, 13) | GENMASK_ULL(11, 10) | GENMASK_ULL(5, 5)) |
| #define SPSR_EL1_AARCH32_RES0_BITS \ |
| - (GENMASK_ULL(63,32) | GENMASK_ULL(23, 22) | GENMASK_ULL(20,20)) |
| + (GENMASK_ULL(63, 32) | GENMASK_ULL(22, 22) | GENMASK_ULL(20, 20)) |
| |
| static int valid_compat_regs(struct user_pt_regs *regs) |
| { |