Skip to content

SSB update 0

Thomas Gleixner historical-speck 2 versions In review

Get series with b4
b4 am [email protected]

Versions newest first · linked by author and title

  1. v2 Latest6 patches 1 replyIn review
  2. v16 patches 10 repliesSuperseded

Changes in v2 from the cover letter

- Fix the fallout from the first version (Kees)

- Rework the state storage a bit in preparation for the dynamic BPF control

Patches in v2 No applies recorded yet

#Subject and filesSizeRepliesApplied
1/6SSB update 1arch/x86/kernel/cpu/bugs.c+3 -20 replies
2/6SSB update 2Documentation/userspace-api/spec_ctrl.rst arch/x86/kernel/cpu/bugs.c fs/proc/array.c +2 more+59 -240 replies
3/6SSB update 3kernel/seccomp.c+1 -10 replies
4/6SSB update 4include/linux/seccomp.h include/uapi/linux/seccomp.h kernel/seccomp.c +1 more+36 -150 replies
5/6SSB update 5arch/x86/kernel/cpu/bugs.c include/linux/nospec.h kernel/seccomp.c+22 -240 replies
6/6SSB update 6Documentation/admin-guide/kernel-parameters.txt arch/x86/include/asm/nospec-branch.h arch/x86/kernel/cpu/bugs.c+41 -180 replies

Reviews trailers per patch

No Reviewed-by, Acked-by or Tested-by trailers for v2 yet.

Read the v2 thread

Cover letter [patch V2 0/6] SSB update 0

Changes since v1:

- Fix the fallout from the first version (Kees)

- Rework the state storage a bit in preparation for the dynamic BPF control

Delta patch below. Git bundle follows in separate mail.

Thanks,

tglx

8<--------------

arch/x86/kernel/cpu/bugs.c +16 -9
index 993a572dc06a..563d8e54c863 100644
@@ -540,10 +540,11 @@ static void ssb_select_mitigation()
 }
 
 #undef pr_fmt
+#define pr_fmt(fmt)     "Speculation prctl: " fmt
 
 static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
 {
-	bool rds = !!test_tsk_thread_flag(task, TIF_RDS);
+	bool update;
 
 	if (ssb_mode != SPEC_STORE_BYPASS_PRCTL &&
 	    ssb_mode != SPEC_STORE_BYPASS_SECCOMP)
@@ -552,16 +553,19 @@ static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
 	switch (ctrl) {
 	case PR_SPEC_ENABLE:
 		/* If speculation is force disabled, enable is not allowed */
-		if (task_spec_force_disable(task))
+		if (task_spec_ssb_force_disable(task))
 			return -EPERM;
-		clear_tsk_thread_flag(task, TIF_RDS);
+		task_clear_spec_ssb_disable(task);
+		update = test_and_clear_tsk_thread_flag(task, TIF_RDS);
 		break;
 	case PR_SPEC_DISABLE:
-		set_tsk_thread_flag(task, TIF_RDS);
+		task_set_spec_ssb_disable(task);
+		update = !test_and_set_tsk_thread_flag(task, TIF_RDS);
 		break;
 	case PR_SPEC_FORCE_DISABLE:
-		set_tsk_thread_flag(task, TIF_RDS);
-		task_set_spec_force_disable(task);
+		task_set_spec_ssb_disable(task);
+		task_set_spec_ssb_force_disable(task);
+		update = !test_and_set_tsk_thread_flag(task, TIF_RDS);
 		break;
 	default:
 		return -ERANGE;
@@ -571,7 +575,7 @@ static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
 	 * If being set on non-current task, delay setting the CPU
 	 * mitigation until it is next scheduled.
 	 */
-	if (task == current && rds != !!test_tsk_thread_flag(task, TIF_RDS))
+	if (task == current && update)
 		speculative_store_bypass_update();
 
 	return 0;
@@ -588,21 +592,24 @@ int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
 	}
 }
 
+#ifdef CONFIG_SECCOMP
 void arch_seccomp_spec_mitigate(struct task_struct *task)
 {
 	if (ssb_mode == SPEC_STORE_BYPASS_SECCOMP)
 		ssb_prctl_set(task, PR_SPEC_FORCE_DISABLE);
 }
+#endif
 
 static int ssb_prctl_get(struct task_struct *task)
 {
 	switch (ssb_mode) {
 	case SPEC_STORE_BYPASS_DISABLE:
 		return PR_SPEC_DISABLE;
+	case SPEC_STORE_BYPASS_SECCOMP:
 	case SPEC_STORE_BYPASS_PRCTL:
-		if (task_spec_force_disable(task))
+		if (task_spec_ssb_force_disable(task))
 			return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE;
-		if (test_tsk_thread_flag(task, TIF_RDS))
+		if (task_spec_ssb_disable(task))
 			return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
 		return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
 	default:
include/linux/sched.h +8 -4
index dfbe5c3b8482..e4218d4deba0 100644
@@ -1393,8 +1393,8 @@ static inline bool is_percpu_thread(void)
 #define PFA_NO_NEW_PRIVS		0	/* May not gain new privileges. */
 #define PFA_SPREAD_PAGE			1	/* Spread page cache over cpuset */
 #define PFA_SPREAD_SLAB			2	/* Spread some slab caches over cpuset */
-#define PFA_SPEC_FORCE_DISABLE		3	/* Force disable speculation */
-
+#define PFA_SPEC_SSB_DISABLE		3	/* Speculative Store Bypass disabled */
+#define PFA_SPEC_SSB_FORCE_DISABLE	4	/* Speculative Store Bypass force disabled*/
 
 #define TASK_PFA_TEST(name, func)					\
 	static inline bool task_##func(struct task_struct *p)		\
@@ -1419,8 +1419,12 @@ TASK_PFA_TEST(SPREAD_SLAB, spread_slab)
 TASK_PFA_SET(SPREAD_SLAB, spread_slab)
 TASK_PFA_CLEAR(SPREAD_SLAB, spread_slab)
 
-TASK_PFA_TEST(SPEC_FORCE_DISABLE, spec_force_disable)
-TASK_PFA_SET(SPEC_FORCE_DISABLE, spec_force_disable)
+TASK_PFA_TEST(SPEC_SSB_DISABLE, spec_ssb_disable)
+TASK_PFA_SET(SPEC_SSB_DISABLE, spec_ssb_disable)
+TASK_PFA_CLEAR(SPEC_SSB_DISABLE, spec_ssb_disable)
+
+TASK_PFA_TEST(SPEC_SSB_FORCE_DISABLE, spec_ssb_force_disable)
+TASK_PFA_SET(SPEC_SSB_FORCE_DISABLE, spec_ssb_force_disable)
 
 static inline void
 current_restore_flags(unsigned long orig_flags, unsigned long flags)
include/linux/seccomp.h +3 -2
index c723a5c4e3ff..e5320f6c8654 100644
@@ -4,8 +4,9 @@
 
 #include <uapi/linux/seccomp.h>
 
-#define SECCOMP_FILTER_FLAG_MASK	(SECCOMP_FILTER_FLAG_TSYNC | \
-					 SECCOMP_FILTER_FLAG_LOG)
+#define SECCOMP_FILTER_FLAG_MASK	(SECCOMP_FILTER_FLAG_TSYNC	| \
+					 SECCOMP_FILTER_FLAG_LOG	| \
+					 SECCOMP_FILTER_FLAG_SPEC_ALLOW)
 
 #ifdef CONFIG_SECCOMP
 
include/uapi/linux/seccomp.h +3 -3
index f88b9e6c32c6..9efc0e73d50b 100644
@@ -17,9 +17,9 @@
 #define SECCOMP_GET_ACTION_AVAIL	2
 
 /* Valid flags for SECCOMP_SET_MODE_FILTER */
-#define SECCOMP_FILTER_FLAG_TSYNC	1
-#define SECCOMP_FILTER_FLAG_LOG		2
-#define SECCOMP_FILTER_FLAG_SPEC_ALLOW	3
+#define SECCOMP_FILTER_FLAG_TSYNC	(1UL << 0)
+#define SECCOMP_FILTER_FLAG_LOG		(1UL << 1)
+#define SECCOMP_FILTER_FLAG_SPEC_ALLOW	(1UL << 2)
 
 /*
  * All BPF programs must return a 32-bit value.
tools/testing/selftests/seccomp/seccomp_bpf.c +14 -3
index c281d961c935..e1473234968d 100644
@@ -134,15 +134,15 @@ struct seccomp_data {
 #endif
 
 #ifndef SECCOMP_FILTER_FLAG_TSYNC
-#define SECCOMP_FILTER_FLAG_TSYNC 1
+#define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0)
 #endif
 
 #ifndef SECCOMP_FILTER_FLAG_LOG
-#define SECCOMP_FILTER_FLAG_LOG 2
+#define SECCOMP_FILTER_FLAG_LOG (1UL << 1)
 #endif
 
 #ifndef SECCOMP_FILTER_FLAG_SPEC_ALLOW
-#define SECCOMP_FILTER_FLAG_SPEC_ALLOW 3
+#define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2)
 #endif
 
 #ifndef PTRACE_SECCOMP_GET_METADATA
@@ -2084,7 +2084,18 @@ TEST(detect_seccomp_filter_flags)
 
 	/* Test detection of known-good filter flags */
 	for (i = 0, all_flags = 0; i < ARRAY_SIZE(flags); i++) {
+		int bits = 0;
+
+		flag = flags[i];
+		/* Make sure the flag is a single bit! */
+		while (flag) {
+			if (flag & 0x1)
+				bits ++;
+			flag >>= 1;
+		}
+		ASSERT_EQ(1, bits);
 		flag = flags[i];
+
 		ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL);
 		ASSERT_NE(ENOSYS, errno) {
 			TH_LOG("Kernel does not support seccomp syscall!");