Re: [Patch v5 12/16] x86/speculation: Create PRCTL interface to restrict indirect branch speculation

2018-11-19 Thread Tim Chen
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

2018-11-19 Thread Tim Chen
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

2018-11-17 Thread Jiri Kosina
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

2018-11-17 Thread Jiri Kosina
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

2018-11-16 Thread Tim Chen
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

2018-11-16 Thread Tim Chen
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