aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/userspace-api/spec_ctrl.rst27
-rw-r--r--arch/x86/kernel/cpu/bugs.c12
-rw-r--r--arch/x86/kernel/process.c12
-rw-r--r--include/linux/sched.h5
-rw-r--r--include/uapi/linux/prctl.h1
-rw-r--r--tools/include/uapi/linux/prctl.h1
6 files changed, 46 insertions, 12 deletions
diff --git a/Documentation/userspace-api/spec_ctrl.rst b/Documentation/userspace-api/spec_ctrl.rst
index c4dbe6f7cdae..1129c7550a48 100644
--- a/Documentation/userspace-api/spec_ctrl.rst
+++ b/Documentation/userspace-api/spec_ctrl.rst
@@ -28,18 +28,20 @@ PR_GET_SPECULATION_CTRL returns the state of the speculation misfeature
28which is selected with arg2 of prctl(2). The return value uses bits 0-3 with 28which is selected with arg2 of prctl(2). The return value uses bits 0-3 with
29the following meaning: 29the following meaning:
30 30
31==== ===================== =================================================== 31==== ====================== ==================================================
32Bit Define Description 32Bit Define Description
33==== ===================== =================================================== 33==== ====================== ==================================================
340 PR_SPEC_PRCTL Mitigation can be controlled per task by 340 PR_SPEC_PRCTL Mitigation can be controlled per task by
35 PR_SET_SPECULATION_CTRL. 35 PR_SET_SPECULATION_CTRL.
361 PR_SPEC_ENABLE The speculation feature is enabled, mitigation is 361 PR_SPEC_ENABLE The speculation feature is enabled, mitigation is
37 disabled. 37 disabled.
382 PR_SPEC_DISABLE The speculation feature is disabled, mitigation is 382 PR_SPEC_DISABLE The speculation feature is disabled, mitigation is
39 enabled. 39 enabled.
403 PR_SPEC_FORCE_DISABLE Same as PR_SPEC_DISABLE, but cannot be undone. A 403 PR_SPEC_FORCE_DISABLE Same as PR_SPEC_DISABLE, but cannot be undone. A
41 subsequent prctl(..., PR_SPEC_ENABLE) will fail. 41 subsequent prctl(..., PR_SPEC_ENABLE) will fail.
42==== ===================== =================================================== 424 PR_SPEC_DISABLE_NOEXEC Same as PR_SPEC_DISABLE, but the state will be
43 cleared on :manpage:`execve(2)`.
44==== ====================== ==================================================
43 45
44If all bits are 0 the CPU is not affected by the speculation misfeature. 46If all bits are 0 the CPU is not affected by the speculation misfeature.
45 47
@@ -92,6 +94,7 @@ Speculation misfeature controls
92 * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_ENABLE, 0, 0); 94 * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_ENABLE, 0, 0);
93 * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE, 0, 0); 95 * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE, 0, 0);
94 * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_FORCE_DISABLE, 0, 0); 96 * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_FORCE_DISABLE, 0, 0);
97 * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE_NOEXEC, 0, 0);
95 98
96- PR_SPEC_INDIR_BRANCH: Indirect Branch Speculation in User Processes 99- PR_SPEC_INDIR_BRANCH: Indirect Branch Speculation in User Processes
97 (Mitigate Spectre V2 style attacks against user processes) 100 (Mitigate Spectre V2 style attacks against user processes)
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 01874d54f4fd..2da82eff0eb4 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -798,15 +798,25 @@ static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
798 if (task_spec_ssb_force_disable(task)) 798 if (task_spec_ssb_force_disable(task))
799 return -EPERM; 799 return -EPERM;
800 task_clear_spec_ssb_disable(task); 800 task_clear_spec_ssb_disable(task);
801 task_clear_spec_ssb_noexec(task);
801 task_update_spec_tif(task); 802 task_update_spec_tif(task);
802 break; 803 break;
803 case PR_SPEC_DISABLE: 804 case PR_SPEC_DISABLE:
804 task_set_spec_ssb_disable(task); 805 task_set_spec_ssb_disable(task);
806 task_clear_spec_ssb_noexec(task);
805 task_update_spec_tif(task); 807 task_update_spec_tif(task);
806 break; 808 break;
807 case PR_SPEC_FORCE_DISABLE: 809 case PR_SPEC_FORCE_DISABLE:
808 task_set_spec_ssb_disable(task); 810 task_set_spec_ssb_disable(task);
809 task_set_spec_ssb_force_disable(task); 811 task_set_spec_ssb_force_disable(task);
812 task_clear_spec_ssb_noexec(task);
813 task_update_spec_tif(task);
814 break;
815 case PR_SPEC_DISABLE_NOEXEC:
816 if (task_spec_ssb_force_disable(task))
817 return -EPERM;
818 task_set_spec_ssb_disable(task);
819 task_set_spec_ssb_noexec(task);
810 task_update_spec_tif(task); 820 task_update_spec_tif(task);
811 break; 821 break;
812 default: 822 default:
@@ -885,6 +895,8 @@ static int ssb_prctl_get(struct task_struct *task)
885 case SPEC_STORE_BYPASS_PRCTL: 895 case SPEC_STORE_BYPASS_PRCTL:
886 if (task_spec_ssb_force_disable(task)) 896 if (task_spec_ssb_force_disable(task))
887 return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; 897 return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE;
898 if (task_spec_ssb_noexec(task))
899 return PR_SPEC_PRCTL | PR_SPEC_DISABLE_NOEXEC;
888 if (task_spec_ssb_disable(task)) 900 if (task_spec_ssb_disable(task))
889 return PR_SPEC_PRCTL | PR_SPEC_DISABLE; 901 return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
890 return PR_SPEC_PRCTL | PR_SPEC_ENABLE; 902 return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 90ae0ca51083..58ac7be52c7a 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -255,6 +255,18 @@ void arch_setup_new_exec(void)
255 /* If cpuid was previously disabled for this task, re-enable it. */ 255 /* If cpuid was previously disabled for this task, re-enable it. */
256 if (test_thread_flag(TIF_NOCPUID)) 256 if (test_thread_flag(TIF_NOCPUID))
257 enable_cpuid(); 257 enable_cpuid();
258
259 /*
260 * Don't inherit TIF_SSBD across exec boundary when
261 * PR_SPEC_DISABLE_NOEXEC is used.
262 */
263 if (test_thread_flag(TIF_SSBD) &&
264 task_spec_ssb_noexec(current)) {
265 clear_thread_flag(TIF_SSBD);
266 task_clear_spec_ssb_disable(current);
267 task_clear_spec_ssb_noexec(current);
268 speculation_ctrl_update(task_thread_info(current)->flags);
269 }
258} 270}
259 271
260static inline void switch_to_bitmap(struct thread_struct *prev, 272static inline void switch_to_bitmap(struct thread_struct *prev,
diff --git a/include/linux/sched.h b/include/linux/sched.h
index f9b43c989577..89ddece0b003 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1453,6 +1453,7 @@ static inline bool is_percpu_thread(void)
1453#define PFA_SPEC_SSB_FORCE_DISABLE 4 /* Speculative Store Bypass force disabled*/ 1453#define PFA_SPEC_SSB_FORCE_DISABLE 4 /* Speculative Store Bypass force disabled*/
1454#define PFA_SPEC_IB_DISABLE 5 /* Indirect branch speculation restricted */ 1454#define PFA_SPEC_IB_DISABLE 5 /* Indirect branch speculation restricted */
1455#define PFA_SPEC_IB_FORCE_DISABLE 6 /* Indirect branch speculation permanently restricted */ 1455#define PFA_SPEC_IB_FORCE_DISABLE 6 /* Indirect branch speculation permanently restricted */
1456#define PFA_SPEC_SSB_NOEXEC 7 /* Speculative Store Bypass clear on execve() */
1456 1457
1457#define TASK_PFA_TEST(name, func) \ 1458#define TASK_PFA_TEST(name, func) \
1458 static inline bool task_##func(struct task_struct *p) \ 1459 static inline bool task_##func(struct task_struct *p) \
@@ -1481,6 +1482,10 @@ TASK_PFA_TEST(SPEC_SSB_DISABLE, spec_ssb_disable)
1481TASK_PFA_SET(SPEC_SSB_DISABLE, spec_ssb_disable) 1482TASK_PFA_SET(SPEC_SSB_DISABLE, spec_ssb_disable)
1482TASK_PFA_CLEAR(SPEC_SSB_DISABLE, spec_ssb_disable) 1483TASK_PFA_CLEAR(SPEC_SSB_DISABLE, spec_ssb_disable)
1483 1484
1485TASK_PFA_TEST(SPEC_SSB_NOEXEC, spec_ssb_noexec)
1486TASK_PFA_SET(SPEC_SSB_NOEXEC, spec_ssb_noexec)
1487TASK_PFA_CLEAR(SPEC_SSB_NOEXEC, spec_ssb_noexec)
1488
1484TASK_PFA_TEST(SPEC_SSB_FORCE_DISABLE, spec_ssb_force_disable) 1489TASK_PFA_TEST(SPEC_SSB_FORCE_DISABLE, spec_ssb_force_disable)
1485TASK_PFA_SET(SPEC_SSB_FORCE_DISABLE, spec_ssb_force_disable) 1490TASK_PFA_SET(SPEC_SSB_FORCE_DISABLE, spec_ssb_force_disable)
1486 1491
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
index b4875a93363a..094bb03b9cc2 100644
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
@@ -219,6 +219,7 @@ struct prctl_mm_map {
219# define PR_SPEC_ENABLE (1UL << 1) 219# define PR_SPEC_ENABLE (1UL << 1)
220# define PR_SPEC_DISABLE (1UL << 2) 220# define PR_SPEC_DISABLE (1UL << 2)
221# define PR_SPEC_FORCE_DISABLE (1UL << 3) 221# define PR_SPEC_FORCE_DISABLE (1UL << 3)
222# define PR_SPEC_DISABLE_NOEXEC (1UL << 4)
222 223
223/* Reset arm64 pointer authentication keys */ 224/* Reset arm64 pointer authentication keys */
224#define PR_PAC_RESET_KEYS 54 225#define PR_PAC_RESET_KEYS 54
diff --git a/tools/include/uapi/linux/prctl.h b/tools/include/uapi/linux/prctl.h
index b4875a93363a..094bb03b9cc2 100644
--- a/tools/include/uapi/linux/prctl.h
+++ b/tools/include/uapi/linux/prctl.h
@@ -219,6 +219,7 @@ struct prctl_mm_map {
219# define PR_SPEC_ENABLE (1UL << 1) 219# define PR_SPEC_ENABLE (1UL << 1)
220# define PR_SPEC_DISABLE (1UL << 2) 220# define PR_SPEC_DISABLE (1UL << 2)
221# define PR_SPEC_FORCE_DISABLE (1UL << 3) 221# define PR_SPEC_FORCE_DISABLE (1UL << 3)
222# define PR_SPEC_DISABLE_NOEXEC (1UL << 4)
222 223
223/* Reset arm64 pointer authentication keys */ 224/* Reset arm64 pointer authentication keys */
224#define PR_PAC_RESET_KEYS 54 225#define PR_PAC_RESET_KEYS 54