[PATCH 4.19 058/139] x86/speculation: Add prctl() control for indirect branch speculation

2018-12-04 Thread Greg Kroah-Hartman
4.19-stable review patch.  If anyone has any objections, please let me know.

--

From: Thomas Gleixner t...@linutronix.de

commit 9137bb27e60e554dab694eafa4cca241fa3a694f upstream

Add the PR_SPEC_INDIRECT_BRANCH option for the PR_GET_SPECULATION_CTRL and
PR_SET_SPECULATION_CTRL prctls to allow fine grained per task control of
indirect branch speculation via STIBP and IBPB.

Invocations:
 Check indirect branch speculation status with
 - prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, 0, 0, 0);

 Enable indirect branch speculation with
 - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_ENABLE, 0, 
0);

 Disable indirect branch speculation with
 - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_DISABLE, 0, 
0);

 Force disable indirect branch speculation with
 - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, 
PR_SPEC_FORCE_DISABLE, 0, 0);

See Documentation/userspace-api/spec_ctrl.rst.

Signed-off-by: Tim Chen 
Signed-off-by: Thomas Gleixner 
Reviewed-by: Ingo Molnar 
Cc: Peter Zijlstra 
Cc: Andy Lutomirski 
Cc: Linus Torvalds 
Cc: Jiri Kosina 
Cc: Tom Lendacky 
Cc: Josh Poimboeuf 
Cc: Andrea Arcangeli 
Cc: David Woodhouse 
Cc: Andi Kleen 
Cc: Dave Hansen 
Cc: Casey Schaufler 
Cc: Asit Mallick 
Cc: Arjan van de Ven 
Cc: Jon Masters 
Cc: Waiman Long 
Cc: Greg KH 
Cc: Dave Stewart 
Cc: Kees Cook 
Cc: sta...@vger.kernel.org
Link: https://lkml.kernel.org/r/20181125185005.866780...@linutronix.de
Signed-off-by: Greg Kroah-Hartman 
---
 Documentation/userspace-api/spec_ctrl.rst |9 
 arch/x86/include/asm/nospec-branch.h  |1 
 arch/x86/kernel/cpu/bugs.c|   67 ++
 arch/x86/kernel/process.c |5 ++
 include/linux/sched.h |9 
 include/uapi/linux/prctl.h|1 
 tools/include/uapi/linux/prctl.h  |1 
 7 files changed, 93 insertions(+)

--- 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_INDIRECT_BRANCH, 0, 0, 0);
+   * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_ENABLE, 
0, 0);
+   * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_DISABLE, 
0, 0);
+   * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, 
PR_SPEC_FORCE_DISABLE, 0, 0);
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -232,6 +232,7 @@ enum spectre_v2_mitigation {
 enum spectre_v2_user_mitigation {
SPECTRE_V2_USER_NONE,
SPECTRE_V2_USER_STRICT,
+   SPECTRE_V2_USER_PRCTL,
 };
 
 /* The Speculative Store Bypass disable variants */
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -564,6 +564,8 @@ void arch_smt_update(void)
case SPECTRE_V2_USER_STRICT:
update_stibp_strict();
break;
+   case SPECTRE_V2_USER_PRCTL:
+   break;
}
 
mutex_unlock(_ctrl_mutex);
@@ -750,12 +752,50 @@ static int ssb_prctl_set(struct task_str
return 0;
 }
 
+static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
+{
+   switch (ctrl) {
+   case PR_SPEC_ENABLE:
+   if (spectre_v2_user == SPECTRE_V2_USER_NONE)
+   return 0;
+   /*
+* Indirect branch speculation is always disabled in strict
+* mode.
+*/
+   if (spectre_v2_user == SPECTRE_V2_USER_STRICT)
+   return -EPERM;
+   task_clear_spec_ib_disable(task);
+   task_update_spec_tif(task);
+   break;
+   case PR_SPEC_DISABLE:
+   case PR_SPEC_FORCE_DISABLE:
+   /*
+* Indirect branch speculation is always allowed when
+* mitigation is force disabled.
+*/
+   if (spectre_v2_user == SPECTRE_V2_USER_NONE)
+   return -EPERM;
+   if (spectre_v2_user == SPECTRE_V2_USER_STRICT)
+   return 0;
+   task_set_spec_ib_disable(task);
+   if (ctrl == PR_SPEC_FORCE_DISABLE)
+   task_set_spec_ib_force_disable(task);
+   task_update_spec_tif(task);
+   break;
+   default:
+   return -ERANGE;
+   }
+   return 0;
+}
+
 int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,

[PATCH 4.19 058/139] x86/speculation: Add prctl() control for indirect branch speculation

2018-12-04 Thread Greg Kroah-Hartman
4.19-stable review patch.  If anyone has any objections, please let me know.

--

From: Thomas Gleixner t...@linutronix.de

commit 9137bb27e60e554dab694eafa4cca241fa3a694f upstream

Add the PR_SPEC_INDIRECT_BRANCH option for the PR_GET_SPECULATION_CTRL and
PR_SET_SPECULATION_CTRL prctls to allow fine grained per task control of
indirect branch speculation via STIBP and IBPB.

Invocations:
 Check indirect branch speculation status with
 - prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, 0, 0, 0);

 Enable indirect branch speculation with
 - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_ENABLE, 0, 
0);

 Disable indirect branch speculation with
 - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_DISABLE, 0, 
0);

 Force disable indirect branch speculation with
 - prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, 
PR_SPEC_FORCE_DISABLE, 0, 0);

See Documentation/userspace-api/spec_ctrl.rst.

Signed-off-by: Tim Chen 
Signed-off-by: Thomas Gleixner 
Reviewed-by: Ingo Molnar 
Cc: Peter Zijlstra 
Cc: Andy Lutomirski 
Cc: Linus Torvalds 
Cc: Jiri Kosina 
Cc: Tom Lendacky 
Cc: Josh Poimboeuf 
Cc: Andrea Arcangeli 
Cc: David Woodhouse 
Cc: Andi Kleen 
Cc: Dave Hansen 
Cc: Casey Schaufler 
Cc: Asit Mallick 
Cc: Arjan van de Ven 
Cc: Jon Masters 
Cc: Waiman Long 
Cc: Greg KH 
Cc: Dave Stewart 
Cc: Kees Cook 
Cc: sta...@vger.kernel.org
Link: https://lkml.kernel.org/r/20181125185005.866780...@linutronix.de
Signed-off-by: Greg Kroah-Hartman 
---
 Documentation/userspace-api/spec_ctrl.rst |9 
 arch/x86/include/asm/nospec-branch.h  |1 
 arch/x86/kernel/cpu/bugs.c|   67 ++
 arch/x86/kernel/process.c |5 ++
 include/linux/sched.h |9 
 include/uapi/linux/prctl.h|1 
 tools/include/uapi/linux/prctl.h  |1 
 7 files changed, 93 insertions(+)

--- 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_INDIRECT_BRANCH, 0, 0, 0);
+   * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_ENABLE, 
0, 0);
+   * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_DISABLE, 
0, 0);
+   * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, 
PR_SPEC_FORCE_DISABLE, 0, 0);
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -232,6 +232,7 @@ enum spectre_v2_mitigation {
 enum spectre_v2_user_mitigation {
SPECTRE_V2_USER_NONE,
SPECTRE_V2_USER_STRICT,
+   SPECTRE_V2_USER_PRCTL,
 };
 
 /* The Speculative Store Bypass disable variants */
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -564,6 +564,8 @@ void arch_smt_update(void)
case SPECTRE_V2_USER_STRICT:
update_stibp_strict();
break;
+   case SPECTRE_V2_USER_PRCTL:
+   break;
}
 
mutex_unlock(_ctrl_mutex);
@@ -750,12 +752,50 @@ static int ssb_prctl_set(struct task_str
return 0;
 }
 
+static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
+{
+   switch (ctrl) {
+   case PR_SPEC_ENABLE:
+   if (spectre_v2_user == SPECTRE_V2_USER_NONE)
+   return 0;
+   /*
+* Indirect branch speculation is always disabled in strict
+* mode.
+*/
+   if (spectre_v2_user == SPECTRE_V2_USER_STRICT)
+   return -EPERM;
+   task_clear_spec_ib_disable(task);
+   task_update_spec_tif(task);
+   break;
+   case PR_SPEC_DISABLE:
+   case PR_SPEC_FORCE_DISABLE:
+   /*
+* Indirect branch speculation is always allowed when
+* mitigation is force disabled.
+*/
+   if (spectre_v2_user == SPECTRE_V2_USER_NONE)
+   return -EPERM;
+   if (spectre_v2_user == SPECTRE_V2_USER_STRICT)
+   return 0;
+   task_set_spec_ib_disable(task);
+   if (ctrl == PR_SPEC_FORCE_DISABLE)
+   task_set_spec_ib_force_disable(task);
+   task_update_spec_tif(task);
+   break;
+   default:
+   return -ERANGE;
+   }
+   return 0;
+}
+
 int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,