Merge tag 'x86_core_for_5.18_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 CET-IBT (Control-Flow-Integrity) support from Peter Zijlstra: "Add support for Intel CET-IBT, available since Tigerlake (11th gen), which is a coarse grained, hardware based, forward edge Control-Flow-Integrity mechanism where any indirect CALL/JMP must target an ENDBR instruction or suffer #CP. Additionally, since Alderlake (12th gen)/Sapphire-Rapids, speculation is limited to 2 instructions (and typically fewer) on branch targets not starting with ENDBR. CET-IBT also limits speculation of the next sequential instruction after the indirect CALL/JMP [1]. CET-IBT is fundamentally incompatible with retpolines, but provides, as described above, speculation limits itself" [1] https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/branch-history-injection.html * tag 'x86_core_for_5.18_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (53 commits) kvm/emulate: Fix SETcc emulation for ENDBR x86/Kconfig: Only allow CONFIG_X86_KERNEL_IBT with ld.lld >= 14.0.0 x86/Kconfig: Only enable CONFIG_CC_HAS_IBT for clang >= 14.0.0 kbuild: Fixup the IBT kbuild changes x86/Kconfig: Do not allow CONFIG_X86_X32_ABI=y with llvm-objcopy x86: Remove toolchain check for X32 ABI capability x86/alternative: Use .ibt_endbr_seal to seal indirect calls objtool: Find unused ENDBR instructions objtool: Validate IBT assumptions objtool: Add IBT/ENDBR decoding objtool: Read the NOENDBR annotation x86: Annotate idtentry_df() x86,objtool: Move the ASM_REACHABLE annotation to objtool.h x86: Annotate call_on_stack() objtool: Rework ASM_REACHABLE x86: Mark __invalid_creds() __noreturn exit: Mark do_group_exit() __noreturn x86: Mark stop_this_cpu() __noreturn objtool: Ignore extra-symbol code objtool: Rename --duplicate to --lto ...
This commit is contained in:
+40
-8
@@ -1568,17 +1568,34 @@ unsigned long ftrace_location_range(unsigned long start, unsigned long end)
|
||||
}
|
||||
|
||||
/**
|
||||
* ftrace_location - return true if the ip giving is a traced location
|
||||
* ftrace_location - return the ftrace location
|
||||
* @ip: the instruction pointer to check
|
||||
*
|
||||
* Returns rec->ip if @ip given is a pointer to a ftrace location.
|
||||
* That is, the instruction that is either a NOP or call to
|
||||
* the function tracer. It checks the ftrace internal tables to
|
||||
* determine if the address belongs or not.
|
||||
* If @ip matches the ftrace location, return @ip.
|
||||
* If @ip matches sym+0, return sym's ftrace location.
|
||||
* Otherwise, return 0.
|
||||
*/
|
||||
unsigned long ftrace_location(unsigned long ip)
|
||||
{
|
||||
return ftrace_location_range(ip, ip);
|
||||
struct dyn_ftrace *rec;
|
||||
unsigned long offset;
|
||||
unsigned long size;
|
||||
|
||||
rec = lookup_rec(ip, ip);
|
||||
if (!rec) {
|
||||
if (!kallsyms_lookup_size_offset(ip, &size, &offset))
|
||||
goto out;
|
||||
|
||||
/* map sym+0 to __fentry__ */
|
||||
if (!offset)
|
||||
rec = lookup_rec(ip, ip + size - 1);
|
||||
}
|
||||
|
||||
if (rec)
|
||||
return rec->ip;
|
||||
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4962,7 +4979,8 @@ __ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove)
|
||||
{
|
||||
struct ftrace_func_entry *entry;
|
||||
|
||||
if (!ftrace_location(ip))
|
||||
ip = ftrace_location(ip);
|
||||
if (!ip)
|
||||
return -EINVAL;
|
||||
|
||||
if (remove) {
|
||||
@@ -5131,11 +5149,16 @@ int register_ftrace_direct(unsigned long ip, unsigned long addr)
|
||||
struct ftrace_func_entry *entry;
|
||||
struct ftrace_hash *free_hash = NULL;
|
||||
struct dyn_ftrace *rec;
|
||||
int ret = -EBUSY;
|
||||
int ret = -ENODEV;
|
||||
|
||||
mutex_lock(&direct_mutex);
|
||||
|
||||
ip = ftrace_location(ip);
|
||||
if (!ip)
|
||||
goto out_unlock;
|
||||
|
||||
/* See if there's a direct function at @ip already */
|
||||
ret = -EBUSY;
|
||||
if (ftrace_find_rec_direct(ip))
|
||||
goto out_unlock;
|
||||
|
||||
@@ -5243,6 +5266,10 @@ int unregister_ftrace_direct(unsigned long ip, unsigned long addr)
|
||||
|
||||
mutex_lock(&direct_mutex);
|
||||
|
||||
ip = ftrace_location(ip);
|
||||
if (!ip)
|
||||
goto out_unlock;
|
||||
|
||||
entry = find_direct_entry(&ip, NULL);
|
||||
if (!entry)
|
||||
goto out_unlock;
|
||||
@@ -5375,6 +5402,11 @@ int modify_ftrace_direct(unsigned long ip,
|
||||
mutex_lock(&direct_mutex);
|
||||
|
||||
mutex_lock(&ftrace_lock);
|
||||
|
||||
ip = ftrace_location(ip);
|
||||
if (!ip)
|
||||
goto out_unlock;
|
||||
|
||||
entry = find_direct_entry(&ip, &rec);
|
||||
if (!entry)
|
||||
goto out_unlock;
|
||||
|
||||
Reference in New Issue
Block a user