Messages in this thread Patch in this message | | | Date | Tue, 22 Sep 2020 02:21:53 -0700 | Subject | [PATCH v2] PR_SPEC_DISABLE_NOEXEC support for arm64. | From | Anthony Steinhauser <> |
| |
Support of Spectre v4 PR_SPEC_DISABLE_NOEXEC mitigation mode for on arm64.
PR_SPEC_DISABLE_NOEXEC turns the mitigation on, but it is automatically turned off whenever a new program is being execve'ed.
Signed-off-by: Anthony Steinhauser <asteinhauser@google.com> ---
I added the "#include <linux/sched/task_stack.h>" line to the arch/arm64/kernel/proton-pack.c file just to make the kernel compilable. It is not a part of the PR_SPEC_DISABLE_NOEXEC implementation.
arch/arm64/kernel/process.c | 7 +++++++ arch/arm64/kernel/proton-pack.c | 35 +++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+)
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 9dbd35b95253..5ac43b743696 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -391,6 +391,13 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start, ptrauth_thread_init_kernel(p); + if (task_spec_ssb_noexec(current)) { + clear_thread_flag(TIF_SSBD); + task_clear_spec_ssb_disable(current); + task_clear_spec_ssb_noexec(current); + spectre_v4_enable_task_mitigation(current); + } + if (likely(!(p->flags & PF_KTHREAD))) { *childregs = *current_pt_regs(); childregs->regs[0] = 0; diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c index b1ea935fd948..566c2304bba7 100644 --- a/arch/arm64/kernel/proton-pack.c +++ b/arch/arm64/kernel/proton-pack.c @@ -22,6 +22,7 @@ #include <linux/device.h> #include <linux/nospec.h> #include <linux/prctl.h> +#include <linux/sched/task_stack.h> #include <asm/spectre.h> #include <asm/traps.h> @@ -681,6 +682,7 @@ static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl) return -EPERM; task_clear_spec_ssb_disable(task); + task_clear_spec_ssb_noexec(task); clear_tsk_thread_flag(task, TIF_SSBD); break; case PR_SPEC_FORCE_DISABLE: @@ -701,6 +703,36 @@ static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl) return -EPERM; task_set_spec_ssb_disable(task); + task_clear_spec_ssb_noexec(task); + set_tsk_thread_flag(task, TIF_SSBD); + break; + case PR_SPEC_DISABLE_NOEXEC: + /* Disable speculation (enable mitigation), but don't inherit + * the mitigation when a new program is execve'd. + * + * Force disabled speculation prevents it from being + * re-enabled even after exec. + */ + if (task_spec_ssb_force_disable(task)) + return -EPERM; + + /* + * If the mitigation is forced on, then speculation is forced + * of unconditionally and we revent it from being + * re-enabled even after exec. + */ + if (spectre_v4_mitigations_on()) + return -EPERM; + + /* + * If the mitigation is forced off, then speculation is forced + * on and we prevent it from being disabled. + */ + if (spectre_v4_mitigations_off()) + return -EPERM; + + task_set_spec_ssb_disable(task); + task_set_spec_ssb_noexec(task); set_tsk_thread_flag(task, TIF_SSBD); break; default: @@ -746,6 +778,9 @@ static int ssbd_prctl_get(struct task_struct *task) if (task_spec_ssb_force_disable(task)) return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; + if (task_spec_ssb_noexec(task)) + return PR_SPEC_PRCTL | PR_SPEC_DISABLE_NOEXEC; + if (task_spec_ssb_disable(task)) return PR_SPEC_PRCTL | PR_SPEC_DISABLE; -- 2.18.4
| |