Skip to content

Commit e463a09

Browse files
Peter Zijlstrasuryasaimadhu
authored andcommitted
x86: Add straight-line-speculation mitigation
Make use of an upcoming GCC feature to mitigate straight-line-speculation for x86: https://gcc.gnu.org/g:53a643f8568067d7700a9f2facc8ba39974973d3 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102952 https://bugs.llvm.org/show_bug.cgi?id=52323 It's built tested on x86_64-allyesconfig using GCC-12 and GCC-11. Maintenance overhead of this should be fairly low due to objtool validation. Size overhead of all these additional int3 instructions comes to: text data bss dec hex filename 22267751 6933356 2011368 31212475 1dc43bb defconfig-build/vmlinux 22804126 6933356 1470696 31208178 1dc32f2 defconfig-build/vmlinux.sls Or roughly 2.4% additional text. Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 26c44b7 commit e463a09

File tree

10 files changed

+38
-7
lines changed

10 files changed

+38
-7
lines changed

arch/x86/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,18 @@ config RETPOLINE
472472
branches. Requires a compiler with -mindirect-branch=thunk-extern
473473
support for full protection. The kernel may run slower.
474474

475+
config CC_HAS_SLS
476+
def_bool $(cc-option,-mharden-sls=all)
477+
478+
config SLS
479+
bool "Mitigate Straight-Line-Speculation"
480+
depends on CC_HAS_SLS && X86_64
481+
default n
482+
help
483+
Compile the kernel with straight-line-speculation options to guard
484+
against straight line speculation. The kernel image might be slightly
485+
larger.
486+
475487
config X86_CPU_RESCTRL
476488
bool "x86 CPU resource control support"
477489
depends on X86 && (CPU_SUP_INTEL || CPU_SUP_AMD)

arch/x86/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,10 @@ ifdef CONFIG_RETPOLINE
191191
endif
192192
endif
193193

194+
ifdef CONFIG_SLS
195+
KBUILD_CFLAGS += -mharden-sls=all
196+
endif
197+
194198
KBUILD_LDFLAGS += -m elf_$(UTS_MACHINE)
195199

196200
ifdef CONFIG_LTO_CLANG

arch/x86/include/asm/linkage.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,19 @@
1818
#define __ALIGN_STR __stringify(__ALIGN)
1919
#endif
2020

21+
#ifdef CONFIG_SLS
22+
#define RET ret; int3
23+
#else
24+
#define RET ret
25+
#endif
26+
2127
#else /* __ASSEMBLY__ */
2228

29+
#ifdef CONFIG_SLS
30+
#define ASM_RET "ret; int3\n\t"
31+
#else
2332
#define ASM_RET "ret\n\t"
33+
#endif
2434

2535
#endif /* __ASSEMBLY__ */
2636

arch/x86/include/asm/static_call.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
__ARCH_DEFINE_STATIC_CALL_TRAMP(name, ".byte 0xe9; .long " #func " - (. + 4)")
3737

3838
#define ARCH_DEFINE_STATIC_CALL_NULL_TRAMP(name) \
39-
__ARCH_DEFINE_STATIC_CALL_TRAMP(name, "ret; nop; nop; nop; nop")
39+
__ARCH_DEFINE_STATIC_CALL_TRAMP(name, "ret; int3; nop; nop; nop")
4040

4141

4242
#define ARCH_ADD_TRAMP_KEY(name) \

arch/x86/kernel/ftrace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ union ftrace_op_code_union {
303303
} __attribute__((packed));
304304
};
305305

306-
#define RET_SIZE 1
306+
#define RET_SIZE 1 + IS_ENABLED(CONFIG_SLS)
307307

308308
static unsigned long
309309
create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)

arch/x86/kernel/static_call.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ enum insn_type {
1717
*/
1818
static const u8 xor5rax[] = { 0x66, 0x66, 0x48, 0x31, 0xc0 };
1919

20+
static const u8 retinsn[] = { RET_INSN_OPCODE, 0xcc, 0xcc, 0xcc, 0xcc };
21+
2022
static void __ref __static_call_transform(void *insn, enum insn_type type, void *func)
2123
{
2224
const void *emulate = NULL;
@@ -42,8 +44,7 @@ static void __ref __static_call_transform(void *insn, enum insn_type type, void
4244
break;
4345

4446
case RET:
45-
code = text_gen_insn(RET_INSN_OPCODE, insn, func);
46-
size = RET_INSN_SIZE;
47+
code = &retinsn;
4748
break;
4849
}
4950

arch/x86/lib/memmove_64.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ SYM_FUNC_START(__memmove)
4040
/* FSRM implies ERMS => no length checks, do the copy directly */
4141
.Lmemmove_begin_forward:
4242
ALTERNATIVE "cmp $0x20, %rdx; jb 1f", "", X86_FEATURE_FSRM
43-
ALTERNATIVE "", "movq %rdx, %rcx; rep movsb; RET", X86_FEATURE_ERMS
43+
ALTERNATIVE "", __stringify(movq %rdx, %rcx; rep movsb; RET), X86_FEATURE_ERMS
4444

4545
/*
4646
* movsq instruction have many startup latency

arch/x86/lib/retpoline.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ SYM_INNER_LABEL(__x86_indirect_thunk_\reg, SYM_L_GLOBAL)
3434

3535
ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \
3636
__stringify(RETPOLINE \reg), X86_FEATURE_RETPOLINE, \
37-
__stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_AMD
37+
__stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg; int3), X86_FEATURE_RETPOLINE_AMD
3838

3939
.endm
4040

scripts/Makefile.build

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,8 @@ objtool_args = \
234234
$(if $(CONFIG_GCOV_KERNEL)$(CONFIG_LTO_CLANG), --no-unreachable)\
235235
$(if $(CONFIG_RETPOLINE), --retpoline) \
236236
$(if $(CONFIG_X86_SMAP), --uaccess) \
237-
$(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount)
237+
$(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \
238+
$(if $(CONFIG_SLS), --sls)
238239

239240
cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@)
240241
cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd)

scripts/link-vmlinux.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ objtool_link()
139139
if [ -n "${CONFIG_X86_SMAP}" ]; then
140140
objtoolopt="${objtoolopt} --uaccess"
141141
fi
142+
if [ -n "${CONFIG_SLS}" ]; then
143+
objtoolopt="${objtoolopt} --sls"
144+
fi
142145
info OBJTOOL ${1}
143146
tools/objtool/objtool ${objtoolcmd} ${objtoolopt} ${1}
144147
fi

0 commit comments

Comments
 (0)