Skip to content

Commit 00a02d0

Browse files
keesKAGA-KOKO
authored andcommitted
seccomp: Add filter flag to opt-out of SSB mitigation
If a seccomp user is not interested in Speculative Store Bypass mitigation by default, it can set the new SECCOMP_FILTER_FLAG_SPEC_ALLOW flag when adding filters. Signed-off-by: Kees Cook <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]>
1 parent b849a81 commit 00a02d0

File tree

4 files changed

+36
-15
lines changed

4 files changed

+36
-15
lines changed

include/linux/seccomp.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
#include <uapi/linux/seccomp.h>
66

7-
#define SECCOMP_FILTER_FLAG_MASK (SECCOMP_FILTER_FLAG_TSYNC | \
8-
SECCOMP_FILTER_FLAG_LOG)
7+
#define SECCOMP_FILTER_FLAG_MASK (SECCOMP_FILTER_FLAG_TSYNC | \
8+
SECCOMP_FILTER_FLAG_LOG | \
9+
SECCOMP_FILTER_FLAG_SPEC_ALLOW)
910

1011
#ifdef CONFIG_SECCOMP
1112

include/uapi/linux/seccomp.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
#define SECCOMP_GET_ACTION_AVAIL 2
1818

1919
/* Valid flags for SECCOMP_SET_MODE_FILTER */
20-
#define SECCOMP_FILTER_FLAG_TSYNC 1
21-
#define SECCOMP_FILTER_FLAG_LOG 2
20+
#define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0)
21+
#define SECCOMP_FILTER_FLAG_LOG (1UL << 1)
22+
#define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2)
2223

2324
/*
2425
* All BPF programs must return a 32-bit value.

kernel/seccomp.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,8 @@ static inline void spec_mitigate(struct task_struct *task,
243243
}
244244

245245
static inline void seccomp_assign_mode(struct task_struct *task,
246-
unsigned long seccomp_mode)
246+
unsigned long seccomp_mode,
247+
unsigned long flags)
247248
{
248249
assert_spin_locked(&task->sighand->siglock);
249250

@@ -253,8 +254,9 @@ static inline void seccomp_assign_mode(struct task_struct *task,
253254
* filter) is set.
254255
*/
255256
smp_mb__before_atomic();
256-
/* Assume seccomp processes want speculation flaw mitigation. */
257-
spec_mitigate(task, PR_SPEC_STORE_BYPASS);
257+
/* Assume default seccomp processes want spec flaw mitigation. */
258+
if ((flags & SECCOMP_FILTER_FLAG_SPEC_ALLOW) == 0)
259+
spec_mitigate(task, PR_SPEC_STORE_BYPASS);
258260
set_tsk_thread_flag(task, TIF_SECCOMP);
259261
}
260262

@@ -322,7 +324,7 @@ static inline pid_t seccomp_can_sync_threads(void)
322324
* without dropping the locks.
323325
*
324326
*/
325-
static inline void seccomp_sync_threads(void)
327+
static inline void seccomp_sync_threads(unsigned long flags)
326328
{
327329
struct task_struct *thread, *caller;
328330

@@ -363,7 +365,8 @@ static inline void seccomp_sync_threads(void)
363365
* allow one thread to transition the other.
364366
*/
365367
if (thread->seccomp.mode == SECCOMP_MODE_DISABLED)
366-
seccomp_assign_mode(thread, SECCOMP_MODE_FILTER);
368+
seccomp_assign_mode(thread, SECCOMP_MODE_FILTER,
369+
flags);
367370
}
368371
}
369372

@@ -486,7 +489,7 @@ static long seccomp_attach_filter(unsigned int flags,
486489

487490
/* Now that the new filter is in place, synchronize to all threads. */
488491
if (flags & SECCOMP_FILTER_FLAG_TSYNC)
489-
seccomp_sync_threads();
492+
seccomp_sync_threads(flags);
490493

491494
return 0;
492495
}
@@ -835,7 +838,7 @@ static long seccomp_set_mode_strict(void)
835838
#ifdef TIF_NOTSC
836839
disable_TSC();
837840
#endif
838-
seccomp_assign_mode(current, seccomp_mode);
841+
seccomp_assign_mode(current, seccomp_mode, 0);
839842
ret = 0;
840843

841844
out:
@@ -893,7 +896,7 @@ static long seccomp_set_mode_filter(unsigned int flags,
893896
/* Do not free the successfully attached filter. */
894897
prepared = NULL;
895898

896-
seccomp_assign_mode(current, seccomp_mode);
899+
seccomp_assign_mode(current, seccomp_mode, flags);
897900
out:
898901
spin_unlock_irq(&current->sighand->siglock);
899902
if (flags & SECCOMP_FILTER_FLAG_TSYNC)

tools/testing/selftests/seccomp/seccomp_bpf.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,15 @@ struct seccomp_data {
134134
#endif
135135

136136
#ifndef SECCOMP_FILTER_FLAG_TSYNC
137-
#define SECCOMP_FILTER_FLAG_TSYNC 1
137+
#define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0)
138138
#endif
139139

140140
#ifndef SECCOMP_FILTER_FLAG_LOG
141-
#define SECCOMP_FILTER_FLAG_LOG 2
141+
#define SECCOMP_FILTER_FLAG_LOG (1UL << 1)
142+
#endif
143+
144+
#ifndef SECCOMP_FILTER_FLAG_SPEC_ALLOW
145+
#define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2)
142146
#endif
143147

144148
#ifndef PTRACE_SECCOMP_GET_METADATA
@@ -2072,14 +2076,26 @@ TEST(seccomp_syscall_mode_lock)
20722076
TEST(detect_seccomp_filter_flags)
20732077
{
20742078
unsigned int flags[] = { SECCOMP_FILTER_FLAG_TSYNC,
2075-
SECCOMP_FILTER_FLAG_LOG };
2079+
SECCOMP_FILTER_FLAG_LOG,
2080+
SECCOMP_FILTER_FLAG_SPEC_ALLOW };
20762081
unsigned int flag, all_flags;
20772082
int i;
20782083
long ret;
20792084

20802085
/* Test detection of known-good filter flags */
20812086
for (i = 0, all_flags = 0; i < ARRAY_SIZE(flags); i++) {
2087+
int bits = 0;
2088+
20822089
flag = flags[i];
2090+
/* Make sure the flag is a single bit! */
2091+
while (flag) {
2092+
if (flag & 0x1)
2093+
bits ++;
2094+
flag >>= 1;
2095+
}
2096+
ASSERT_EQ(1, bits);
2097+
flag = flags[i];
2098+
20832099
ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL);
20842100
ASSERT_NE(ENOSYS, errno) {
20852101
TH_LOG("Kernel does not support seccomp syscall!");

0 commit comments

Comments
 (0)