On Tue, 27 Nov 2018, Jiri Kosina wrote:
> On Mon, 26 Nov 2018, Thomas Gleixner wrote:
> 
> How about the minimalistic aproach below? (only compile tested so far, 
> applies on top of your latest WIP.x86/pti branch). The downside of course 
> is wasting another TIF bit.

We need to waste another TIF bit in any case.

>        *
>        * This can only happen for SECCOMP mitigation. For PRCTL it's
>        * always the current task.
> +      *
> +      * If we are updating non-current task, set a flag for it to always
> +      * perform the MSR sync on a first context switch, to make sure
> +      * the TIF_SPEC_IB above is not out of sync with the MSR value during
> +      * task's runtime.
>        */
>       if (tsk == current && update)
>               speculation_ctrl_update_current();
> +     else
> +             set_tsk_thread_flag(tsk, TIF_SPEC_UPDATE);
> +
>  }
>  
>  static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
> diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
> index 3f5e351bdd37..78208234e63e 100644
> --- a/arch/x86/kernel/process.c
> +++ b/arch/x86/kernel/process.c
> @@ -449,8 +449,20 @@ static __always_inline void 
> __speculation_ctrl_update(unsigned long tifp,
>        * otherwise avoid the MSR write.
>        */
>       if (IS_ENABLED(CONFIG_SMP) &&
> -         static_branch_unlikely(&switch_to_cond_stibp))
> +         static_branch_unlikely(&switch_to_cond_stibp)) {
>               updmsr |= !!(tif_diff & _TIF_SPEC_IB);
> +             /*
> +              * We need to update the MSR if remote task did set
> +              * TIF_SPEC_UPDATE on us, and therefore MSR value and
> +              * the TIF_SPEC_IB values might be out of sync.
> +              *
> +              * This can only happen if seccomp task has updated
> +              * one of its remote threads.
> +              */
> +             if (IS_ENABLED(CONFIG_SECCOMP) && !updmsr &&
> +                             (tifn & TIF_SPEC_UPDATE))
> +                     updmsr = true;
> +     }
>  
>       if (updmsr)
>               spec_ctrl_update_msr(tifn);
> @@ -496,6 +508,8 @@ void __switch_to_xtra(struct task_struct *prev_p, struct 
> task_struct *next_p)
>               set_cpuid_faulting(!!(tifn & _TIF_NOCPUID));
>  
>       __speculation_ctrl_update(tifp, tifn);
> +     if (IS_ENABLED(CONFIG_SECCOMP))
> +             clear_tsk_thread_flag(next_p, TIF_SPEC_UPDATE);

That's racy and does not prevent the situation because the TIF flags are
updated befor the UPDATE bit is set. So __speculation_ctrl_update() might
see the new bits, but not TIF_SPEC_UPDATE. You really need shadow storage
to avoid that.

Thanks,

        tglx

Reply via email to