Merge tag 'x86_core_for_v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 core updates from Borislav Petkov:
- Add the call depth tracking mitigation for Retbleed which has been
long in the making. It is a lighterweight software-only fix for
Skylake-based cores where enabling IBRS is a big hammer and causes a
significant performance impact.
What it basically does is, it aligns all kernel functions to 16 bytes
boundary and adds a 16-byte padding before the function, objtool
collects all functions' locations and when the mitigation gets
applied, it patches a call accounting thunk which is used to track
the call depth of the stack at any time.
When that call depth reaches a magical, microarchitecture-specific
value for the Return Stack Buffer, the code stuffs that RSB and
avoids its underflow which could otherwise lead to the Intel variant
of Retbleed.
This software-only solution brings a lot of the lost performance
back, as benchmarks suggest:
https://lore.kernel.org/all/20220915111039.092790446@infradead.org/
That page above also contains a lot more detailed explanation of the
whole mechanism
- Implement a new control flow integrity scheme called FineIBT which is
based on the software kCFI implementation and uses hardware IBT
support where present to annotate and track indirect branches using a
hash to validate them
- Other misc fixes and cleanups
* tag 'x86_core_for_v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (80 commits)
x86/paravirt: Use common macro for creating simple asm paravirt functions
x86/paravirt: Remove clobber bitmask from .parainstructions
x86/debug: Include percpu.h in debugreg.h to get DECLARE_PER_CPU() et al
x86/cpufeatures: Move X86_FEATURE_CALL_DEPTH from bit 18 to bit 19 of word 11, to leave space for WIP X86_FEATURE_SGX_EDECCSSA bit
x86/Kconfig: Enable kernel IBT by default
x86,pm: Force out-of-line memcpy()
objtool: Fix weak hole vs prefix symbol
objtool: Optimize elf_dirty_reloc_sym()
x86/cfi: Add boot time hash randomization
x86/cfi: Boot time selection of CFI scheme
x86/ibt: Implement FineIBT
objtool: Add --cfi to generate the .cfi_sites section
x86: Add prefix symbols for function padding
objtool: Add option to generate prefix symbols
objtool: Avoid O(bloody terrible) behaviour -- an ode to libelf
objtool: Slice up elf_create_section_symbol()
kallsyms: Revert "Take callthunks into account"
x86: Unconfuse CONFIG_ and X86_FEATURE_ namespaces
x86/retpoline: Fix crash printing warning
x86/paravirt: Fix a !PARAVIRT build warning
...
This commit is contained in:
@@ -74,10 +74,11 @@ void *module_alloc(unsigned long size)
|
||||
return NULL;
|
||||
|
||||
p = __vmalloc_node_range(size, MODULE_ALIGN,
|
||||
MODULES_VADDR + get_module_load_offset(),
|
||||
MODULES_END, gfp_mask,
|
||||
PAGE_KERNEL, VM_DEFER_KMEMLEAK, NUMA_NO_NODE,
|
||||
__builtin_return_address(0));
|
||||
MODULES_VADDR + get_module_load_offset(),
|
||||
MODULES_END, gfp_mask, PAGE_KERNEL,
|
||||
VM_FLUSH_RESET_PERMS | VM_DEFER_KMEMLEAK,
|
||||
NUMA_NO_NODE, __builtin_return_address(0));
|
||||
|
||||
if (p && (kasan_alloc_module_shadow(p, size, gfp_mask) < 0)) {
|
||||
vfree(p);
|
||||
return NULL;
|
||||
@@ -253,7 +254,8 @@ int module_finalize(const Elf_Ehdr *hdr,
|
||||
{
|
||||
const Elf_Shdr *s, *alt = NULL, *locks = NULL,
|
||||
*para = NULL, *orc = NULL, *orc_ip = NULL,
|
||||
*retpolines = NULL, *returns = NULL, *ibt_endbr = NULL;
|
||||
*retpolines = NULL, *returns = NULL, *ibt_endbr = NULL,
|
||||
*calls = NULL, *cfi = NULL;
|
||||
char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
|
||||
|
||||
for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
|
||||
@@ -271,6 +273,10 @@ int module_finalize(const Elf_Ehdr *hdr,
|
||||
retpolines = s;
|
||||
if (!strcmp(".return_sites", secstrings + s->sh_name))
|
||||
returns = s;
|
||||
if (!strcmp(".call_sites", secstrings + s->sh_name))
|
||||
calls = s;
|
||||
if (!strcmp(".cfi_sites", secstrings + s->sh_name))
|
||||
cfi = s;
|
||||
if (!strcmp(".ibt_endbr_seal", secstrings + s->sh_name))
|
||||
ibt_endbr = s;
|
||||
}
|
||||
@@ -283,6 +289,22 @@ int module_finalize(const Elf_Ehdr *hdr,
|
||||
void *pseg = (void *)para->sh_addr;
|
||||
apply_paravirt(pseg, pseg + para->sh_size);
|
||||
}
|
||||
if (retpolines || cfi) {
|
||||
void *rseg = NULL, *cseg = NULL;
|
||||
unsigned int rsize = 0, csize = 0;
|
||||
|
||||
if (retpolines) {
|
||||
rseg = (void *)retpolines->sh_addr;
|
||||
rsize = retpolines->sh_size;
|
||||
}
|
||||
|
||||
if (cfi) {
|
||||
cseg = (void *)cfi->sh_addr;
|
||||
csize = cfi->sh_size;
|
||||
}
|
||||
|
||||
apply_fineibt(rseg, rseg + rsize, cseg, cseg + csize);
|
||||
}
|
||||
if (retpolines) {
|
||||
void *rseg = (void *)retpolines->sh_addr;
|
||||
apply_retpolines(rseg, rseg + retpolines->sh_size);
|
||||
@@ -296,6 +318,21 @@ int module_finalize(const Elf_Ehdr *hdr,
|
||||
void *aseg = (void *)alt->sh_addr;
|
||||
apply_alternatives(aseg, aseg + alt->sh_size);
|
||||
}
|
||||
if (calls || para) {
|
||||
struct callthunk_sites cs = {};
|
||||
|
||||
if (calls) {
|
||||
cs.call_start = (void *)calls->sh_addr;
|
||||
cs.call_end = (void *)calls->sh_addr + calls->sh_size;
|
||||
}
|
||||
|
||||
if (para) {
|
||||
cs.pv_start = (void *)para->sh_addr;
|
||||
cs.pv_end = (void *)para->sh_addr + para->sh_size;
|
||||
}
|
||||
|
||||
callthunks_patch_module_calls(&cs, me);
|
||||
}
|
||||
if (ibt_endbr) {
|
||||
void *iseg = (void *)ibt_endbr->sh_addr;
|
||||
apply_ibt_endbr(iseg, iseg + ibt_endbr->sh_size);
|
||||
|
||||
Reference in New Issue
Block a user