Re: [Patch v5 12/16] x86/speculation: Create PRCTL interface to restrict indirect branch speculation
On 11/17/2018 01:53 AM, Jiri Kosina wrote: > On Fri, 16 Nov 2018, Tim Chen wrote: > > > I think that the fact that this talks about "indirect branch predictions" > in general terms, but really controls only the SMT aspect of it (STIBP), > as quite confusing. > > So I believe it should either be renamed, or actually control semantics of > IBPB as well, no? It does control STIBP. You have suggestion on an alternative name? Tim
Re: [Patch v5 12/16] x86/speculation: Create PRCTL interface to restrict indirect branch speculation
On 11/17/2018 01:53 AM, Jiri Kosina wrote: > On Fri, 16 Nov 2018, Tim Chen wrote: > > > I think that the fact that this talks about "indirect branch predictions" > in general terms, but really controls only the SMT aspect of it (STIBP), > as quite confusing. > > So I believe it should either be renamed, or actually control semantics of > IBPB as well, no? It does control STIBP. You have suggestion on an alternative name? Tim
Re: [Patch v5 12/16] x86/speculation: Create PRCTL interface to restrict indirect branch speculation
On Fri, 16 Nov 2018, Tim Chen wrote: > Create PRCTL interface to restrict an application's indirect branch > speculation. This will protect the application against spectre v2 attack > from another application. > > Invocations: > Check indirect branch speculation status with > - prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, 0, 0, 0); > > Enable indirect branch speculation with > - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_ENABLE, 0, 0); > > Disable indirect branch speculation with > - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_DISABLE, 0, 0); > > Force disable indirect branch speculation with > - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_FORCE_DISABLE, > 0, 0); > > See Documentation/userspace-api/spec_ctrl.rst. I think that the fact that this talks about "indirect branch predictions" in general terms, but really controls only the SMT aspect of it (STIBP), as quite confusing. So I believe it should either be renamed, or actually control semantics of IBPB as well, no? Thanks, -- Jiri Kosina SUSE Labs
Re: [Patch v5 12/16] x86/speculation: Create PRCTL interface to restrict indirect branch speculation
On Fri, 16 Nov 2018, Tim Chen wrote: > Create PRCTL interface to restrict an application's indirect branch > speculation. This will protect the application against spectre v2 attack > from another application. > > Invocations: > Check indirect branch speculation status with > - prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, 0, 0, 0); > > Enable indirect branch speculation with > - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_ENABLE, 0, 0); > > Disable indirect branch speculation with > - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_DISABLE, 0, 0); > > Force disable indirect branch speculation with > - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_FORCE_DISABLE, > 0, 0); > > See Documentation/userspace-api/spec_ctrl.rst. I think that the fact that this talks about "indirect branch predictions" in general terms, but really controls only the SMT aspect of it (STIBP), as quite confusing. So I believe it should either be renamed, or actually control semantics of IBPB as well, no? Thanks, -- Jiri Kosina SUSE Labs
[Patch v5 12/16] x86/speculation: Create PRCTL interface to restrict indirect branch speculation
Create PRCTL interface to restrict an application's indirect branch speculation. This will protect the application against spectre v2 attack from another application. Invocations: Check indirect branch speculation status with - prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, 0, 0, 0); Enable indirect branch speculation with - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_ENABLE, 0, 0); Disable indirect branch speculation with - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_DISABLE, 0, 0); Force disable indirect branch speculation with - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_FORCE_DISABLE, 0, 0); See Documentation/userspace-api/spec_ctrl.rst. Signed-off-by: Tim Chen --- Documentation/userspace-api/spec_ctrl.rst | 9 arch/x86/kernel/cpu/bugs.c| 80 +++ include/linux/sched.h | 9 include/uapi/linux/prctl.h| 1 + tools/include/uapi/linux/prctl.h | 1 + 5 files changed, 100 insertions(+) diff --git a/Documentation/userspace-api/spec_ctrl.rst b/Documentation/userspace-api/spec_ctrl.rst index 32f3d55..8a4e268 100644 --- a/Documentation/userspace-api/spec_ctrl.rst +++ b/Documentation/userspace-api/spec_ctrl.rst @@ -92,3 +92,12 @@ Speculation misfeature controls * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_ENABLE, 0, 0); * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE, 0, 0); * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_FORCE_DISABLE, 0, 0); + +- PR_SPEC_INDIR_BRANCH: Indirect Branch Speculation in User Processes +(Mitigate Spectre V2 style attacks against user processes) + + Invocations: + * prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, 0, 0, 0); + * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_ENABLE, 0, 0); + * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_DISABLE, 0, 0); + * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_FORCE_DISABLE, 0, 0); diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 21caade..8f5187e 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -773,12 +773,69 @@ static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl) return 0; } +static void set_task_stibp(struct task_struct *tsk, bool stibp_on) +{ + bool update = false; + + if (stibp_on) + update = !test_and_set_tsk_thread_flag(tsk, TIF_STIBP); + else + update = test_and_clear_tsk_thread_flag(tsk, TIF_STIBP); + + if (tsk == current && update) + speculation_ctrl_update_current(); +} + +static int indir_branch_prctl_set(struct task_struct *task, unsigned long ctrl) +{ + switch (ctrl) { + case PR_SPEC_ENABLE: + if (spectre_v2_app2app_enabled == SPECTRE_V2_APP2APP_NONE) + return 0; + /* +* Indirect branch speculation is always disabled in +* strict mode. +*/ + if (spectre_v2_app2app_enabled == SPECTRE_V2_APP2APP_STRICT) + return -EPERM; + task_clear_spec_indir_branch_disable(task); + set_task_stibp(task, false); + break; + case PR_SPEC_DISABLE: + /* +* Indirect branch speculation is always allowed when +* mitigation is force disabled. +*/ + if (spectre_v2_app2app_enabled == SPECTRE_V2_APP2APP_NONE) + return -EPERM; + if (spectre_v2_app2app_enabled == SPECTRE_V2_APP2APP_STRICT) + return 0; + task_set_spec_indir_branch_disable(task); + set_task_stibp(task, true); + break; + case PR_SPEC_FORCE_DISABLE: + if (spectre_v2_app2app_enabled == SPECTRE_V2_APP2APP_NONE) + return -EPERM; + if (spectre_v2_app2app_enabled == SPECTRE_V2_APP2APP_STRICT) + return 0; + task_set_spec_indir_branch_disable(task); + task_set_spec_indir_branch_force_disable(task); + set_task_stibp(task, true); + break; + default: + return -ERANGE; + } + return 0; +} + int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which, unsigned long ctrl) { switch (which) { case PR_SPEC_STORE_BYPASS: return ssb_prctl_set(task, ctrl); + case PR_SPEC_INDIR_BRANCH: + return indir_branch_prctl_set(task, ctrl); default: return -ENODEV; } @@ -811,11 +868,34 @@ static int ssb_prctl_get(struct task_struct *task) } } +static int indir_branch_prctl_get(struct task_struct
[Patch v5 12/16] x86/speculation: Create PRCTL interface to restrict indirect branch speculation
Create PRCTL interface to restrict an application's indirect branch speculation. This will protect the application against spectre v2 attack from another application. Invocations: Check indirect branch speculation status with - prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, 0, 0, 0); Enable indirect branch speculation with - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_ENABLE, 0, 0); Disable indirect branch speculation with - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_DISABLE, 0, 0); Force disable indirect branch speculation with - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_FORCE_DISABLE, 0, 0); See Documentation/userspace-api/spec_ctrl.rst. Signed-off-by: Tim Chen --- Documentation/userspace-api/spec_ctrl.rst | 9 arch/x86/kernel/cpu/bugs.c| 80 +++ include/linux/sched.h | 9 include/uapi/linux/prctl.h| 1 + tools/include/uapi/linux/prctl.h | 1 + 5 files changed, 100 insertions(+) diff --git a/Documentation/userspace-api/spec_ctrl.rst b/Documentation/userspace-api/spec_ctrl.rst index 32f3d55..8a4e268 100644 --- a/Documentation/userspace-api/spec_ctrl.rst +++ b/Documentation/userspace-api/spec_ctrl.rst @@ -92,3 +92,12 @@ Speculation misfeature controls * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_ENABLE, 0, 0); * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE, 0, 0); * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_FORCE_DISABLE, 0, 0); + +- PR_SPEC_INDIR_BRANCH: Indirect Branch Speculation in User Processes +(Mitigate Spectre V2 style attacks against user processes) + + Invocations: + * prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, 0, 0, 0); + * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_ENABLE, 0, 0); + * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_DISABLE, 0, 0); + * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIR_BRANCH, PR_SPEC_FORCE_DISABLE, 0, 0); diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 21caade..8f5187e 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -773,12 +773,69 @@ static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl) return 0; } +static void set_task_stibp(struct task_struct *tsk, bool stibp_on) +{ + bool update = false; + + if (stibp_on) + update = !test_and_set_tsk_thread_flag(tsk, TIF_STIBP); + else + update = test_and_clear_tsk_thread_flag(tsk, TIF_STIBP); + + if (tsk == current && update) + speculation_ctrl_update_current(); +} + +static int indir_branch_prctl_set(struct task_struct *task, unsigned long ctrl) +{ + switch (ctrl) { + case PR_SPEC_ENABLE: + if (spectre_v2_app2app_enabled == SPECTRE_V2_APP2APP_NONE) + return 0; + /* +* Indirect branch speculation is always disabled in +* strict mode. +*/ + if (spectre_v2_app2app_enabled == SPECTRE_V2_APP2APP_STRICT) + return -EPERM; + task_clear_spec_indir_branch_disable(task); + set_task_stibp(task, false); + break; + case PR_SPEC_DISABLE: + /* +* Indirect branch speculation is always allowed when +* mitigation is force disabled. +*/ + if (spectre_v2_app2app_enabled == SPECTRE_V2_APP2APP_NONE) + return -EPERM; + if (spectre_v2_app2app_enabled == SPECTRE_V2_APP2APP_STRICT) + return 0; + task_set_spec_indir_branch_disable(task); + set_task_stibp(task, true); + break; + case PR_SPEC_FORCE_DISABLE: + if (spectre_v2_app2app_enabled == SPECTRE_V2_APP2APP_NONE) + return -EPERM; + if (spectre_v2_app2app_enabled == SPECTRE_V2_APP2APP_STRICT) + return 0; + task_set_spec_indir_branch_disable(task); + task_set_spec_indir_branch_force_disable(task); + set_task_stibp(task, true); + break; + default: + return -ERANGE; + } + return 0; +} + int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which, unsigned long ctrl) { switch (which) { case PR_SPEC_STORE_BYPASS: return ssb_prctl_set(task, ctrl); + case PR_SPEC_INDIR_BRANCH: + return indir_branch_prctl_set(task, ctrl); default: return -ENODEV; } @@ -811,11 +868,34 @@ static int ssb_prctl_get(struct task_struct *task) } } +static int indir_branch_prctl_get(struct task_struct