mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-24 05:04:00 +08:00
arm64: Add support for PR_SPEC_DISABLE_NOEXEC prctl() option
The PR_SPEC_DISABLE_NOEXEC option to the PR_SPEC_STORE_BYPASS prctl() allows the SSB mitigation to be enabled only until the next execve(), at which point the state will revert back to PR_SPEC_ENABLE and the mitigation will be disabled. Add support for PR_SPEC_DISABLE_NOEXEC on arm64. Reported-by: Anthony Steinhauser <asteinhauser@google.com> Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
parent
5c8b0cbd9d
commit
780c083a8f
@ -21,6 +21,7 @@
|
||||
#include <linux/lockdep.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/nospec.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/unistd.h>
|
||||
@ -609,6 +610,11 @@ void arch_setup_new_exec(void)
|
||||
current->mm->context.flags = is_compat_task() ? MMCF_AARCH32 : 0;
|
||||
|
||||
ptrauth_thread_init_user(current);
|
||||
|
||||
if (task_spec_ssb_noexec(current)) {
|
||||
arch_prctl_spec_ctrl_set(current, PR_SPEC_STORE_BYPASS,
|
||||
PR_SPEC_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM64_TAGGED_ADDR_ABI
|
||||
|
@ -660,6 +660,20 @@ void spectre_v4_enable_task_mitigation(struct task_struct *tsk)
|
||||
* prctl() may be necessary even when PSTATE.SSBS can be toggled directly
|
||||
* from userspace.
|
||||
*/
|
||||
static void ssbd_prctl_enable_mitigation(struct task_struct *task)
|
||||
{
|
||||
task_clear_spec_ssb_noexec(task);
|
||||
task_set_spec_ssb_disable(task);
|
||||
set_tsk_thread_flag(task, TIF_SSBD);
|
||||
}
|
||||
|
||||
static void ssbd_prctl_disable_mitigation(struct task_struct *task)
|
||||
{
|
||||
task_clear_spec_ssb_noexec(task);
|
||||
task_clear_spec_ssb_disable(task);
|
||||
clear_tsk_thread_flag(task, TIF_SSBD);
|
||||
}
|
||||
|
||||
static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl)
|
||||
{
|
||||
switch (ctrl) {
|
||||
@ -679,8 +693,7 @@ static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl)
|
||||
if (spectre_v4_mitigations_on())
|
||||
return -EPERM;
|
||||
|
||||
task_clear_spec_ssb_disable(task);
|
||||
clear_tsk_thread_flag(task, TIF_SSBD);
|
||||
ssbd_prctl_disable_mitigation(task);
|
||||
break;
|
||||
case PR_SPEC_FORCE_DISABLE:
|
||||
/* Force disable speculation: force enable mitigation */
|
||||
@ -699,8 +712,22 @@ static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl)
|
||||
if (spectre_v4_mitigations_off())
|
||||
return -EPERM;
|
||||
|
||||
task_set_spec_ssb_disable(task);
|
||||
set_tsk_thread_flag(task, TIF_SSBD);
|
||||
ssbd_prctl_enable_mitigation(task);
|
||||
break;
|
||||
case PR_SPEC_DISABLE_NOEXEC:
|
||||
/* Disable speculation until execve(): enable mitigation */
|
||||
/*
|
||||
* If the mitigation state is forced one way or the other, then
|
||||
* we must fail now before we try to toggle it on execve().
|
||||
*/
|
||||
if (task_spec_ssb_force_disable(task) ||
|
||||
spectre_v4_mitigations_off() ||
|
||||
spectre_v4_mitigations_on()) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
ssbd_prctl_enable_mitigation(task);
|
||||
task_set_spec_ssb_noexec(task);
|
||||
break;
|
||||
default:
|
||||
return -ERANGE;
|
||||
@ -745,6 +772,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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user