Re: [PATCH v2] PR_SPEC_DISABLE_NOEXEC support for arm64.
From: Anthony Steinhauser
Date: Tue Sep 29 2020 - 13:23:04 EST
Thanks a lot Will,
Everything looks good to me now.
On Tue, Sep 29, 2020 at 4:10 AM Will Deacon <will@xxxxxxxxxx> wrote:
>
> Hi Anthony,
>
...
>
> I'll fold in the diff below, which I think solves the problem above; it's
> closer to what you had originally, just refactored a bit and with the
> execve()/fork() issue fixed.
>
> Will
>
> --->8
>
> diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
> index 59f2ceb7a0e5..68b710f1b43f 100644
> --- a/arch/arm64/kernel/proton-pack.c
> +++ b/arch/arm64/kernel/proton-pack.c
> @@ -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 */
> @@ -693,28 +706,33 @@ static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl)
>
> task_set_spec_ssb_force_disable(task);
> fallthrough;
> - case PR_SPEC_DISABLE_NOEXEC:
> - /* Disable speculation until execve(): enable mitigation */
> - fallthrough;
> case PR_SPEC_DISABLE:
> /* Disable speculation: enable mitigation */
> /* Same as PR_SPEC_FORCE_DISABLE */
> 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;
> }
>
> - /* Handle the 'noexec' flag separately to save bloating up the switch */
> - if (ctrl == PR_SPEC_DISABLE_NOEXEC)
> - task_set_spec_ssb_noexec(task);
> - else
> - task_clear_spec_ssb_noexec(task);
> -
> spectre_v4_enable_task_mitigation(task);
> return 0;
> }