kcfi: Prepare for GCC support
Subsystems (23)
Kees Cook
maintainerv2 cover kcfi: Prepare for GCC support
v2:
- integrate "transitional" Kconfig patch[2] (nathan, randy, miguel)
- add arm32 KCFI trap handler
- split pr_info changes (nathan)
- clean up my broken SoB (peter)
- remove Clang from CONFIG_CFI help (jeff)
- add r-b (linus)
v1: https://lore.kernel.org/all/[email protected]/
Hi,
With KCFI support in GCC coming[1], we need to make some (relatively small) changes in the kernel to deal with it:
- move __nocfi out of compilers-clang.h (so GCC can see it too)
- add cfi=debug so future Kees can find fineibt breakage easier
- remove problematic __noinitretpoline usage
- rename CONFIG_CFI_CLANG to CONFIG_CFI (otherwise it is quite confusing)
If I can get some Acks, I will carry this in the hardening tree, unless someone else would like to take it (perhaps tip).
Thanks!
-Kees
[1] https://lore.kernel.org/linux-hardening/[email protected]/
[2] https://lore.kernel.org/all/[email protected]/
Kees Cook (9):
compiler_types.h: Move __nocfi out of compiler-specific header x86/traps: Clarify KCFI instruction layout
x86/cfi: Document the "cfi=" bootparam options x86/cfi: Standardize on common "CFI:" prefix for CFI reports x86/cfi: Add "debug" option to "cfi=" bootparam x86/cfi: Remove __noinitretpoline and __noretpoline
kconfig: Add transitional symbol attribute for migration support
kcfi: Rename CONFIG_CFI_CLANG to CONFIG_CFI
ARM: traps: Implement KCFI trap handler for ARM32
arch/Kconfig | 36 ++++--- arch/arm/Kconfig | 2 +- arch/arm64/Kconfig | 4 +- arch/riscv/Kconfig | 6 +- arch/x86/Kconfig | 12 +-- init/Kconfig | 4 +- kernel/module/Kconfig | 2 +- .../kconfig/tests/err_transitional/Kconfig | 52 +++++++++ scripts/kconfig/tests/transitional/Kconfig | 100 +++++++++++++++++ lib/Kconfig.debug | 2 +- Makefile | 2 +- arch/arm/mm/Makefile | 2 +- arch/riscv/kernel/Makefile | 2 +- arch/riscv/purgatory/Makefile | 2 +- arch/x86/kernel/Makefile | 2 +- arch/x86/purgatory/Makefile | 2 +- kernel/Makefile | 2 +- scripts/kconfig/expr.h | 1 + scripts/kconfig/lexer.l | 1 + scripts/kconfig/parser.y | 47 ++++++++ scripts/kconfig/symbol.c | 16 ++- .../tests/err_transitional/__init__.py | 14 +++ .../tests/err_transitional/expected_stderr | 7 ++ .../kconfig/tests/transitional/__init__.py | 18 ++++ .../tests/transitional/expected_config | 12 +++ .../kconfig/tests/transitional/initial_config | 16 +++ .../admin-guide/kernel-parameters.txt | 18 ++++ Documentation/kbuild/kconfig-language.rst | 32 ++++++ arch/riscv/include/asm/cfi.h | 4 +- arch/x86/include/asm/cfi.h | 4 +- include/asm-generic/vmlinux.lds.h | 2 +- include/linux/cfi.h | 6 +- include/linux/cfi_types.h | 8 +- include/linux/compiler-clang.h | 5 - include/linux/compiler-gcc.h | 4 - include/linux/compiler.h | 2 +- include/linux/compiler_types.h | 4 +- include/linux/init.h | 8 -- tools/include/linux/cfi_types.h | 6 +- tools/perf/util/include/linux/linkage.h | 2 +- arch/arm/mm/cache-fa.S | 2 +- arch/arm/mm/cache-v4.S | 2 +- arch/arm/mm/cache-v4wb.S | 4 +- arch/arm/mm/cache-v4wt.S | 2 +- arch/arm/mm/cache-v6.S | 2 +- arch/arm/mm/cache-v7.S | 2 +- arch/arm/mm/cache-v7m.S | 2 +- arch/arm/mm/proc-arm1020.S | 2 +- arch/arm/mm/proc-arm1020e.S | 2 +- arch/arm/mm/proc-arm1022.S | 2 +- arch/arm/mm/proc-arm1026.S | 2 +- arch/arm/mm/proc-arm920.S | 2 +- arch/arm/mm/proc-arm922.S | 2 +- arch/arm/mm/proc-arm925.S | 2 +- arch/arm/mm/proc-arm926.S | 2 +- arch/arm/mm/proc-arm940.S | 2 +- arch/arm/mm/proc-arm946.S | 2 +- arch/arm/mm/proc-feroceon.S | 2 +- arch/arm/mm/proc-mohawk.S | 2 +- arch/arm/mm/proc-xsc3.S | 2 +- arch/arm/mm/tlb-v4.S | 2 +- arch/arm/kernel/hw_breakpoint.c | 2 +- arch/arm/kernel/traps.c | 102 ++++++++++++++++++ arch/arm64/kernel/debug-monitors.c | 2 +- arch/arm64/kernel/traps.c | 4 +- arch/arm64/kvm/handle_exit.c | 2 +- arch/arm64/net/bpf_jit_comp.c | 2 +- arch/riscv/net/bpf_jit_comp64.c | 4 +- arch/x86/kernel/alternative.c | 44 ++++++-- arch/x86/kernel/cfi.c | 2 +- arch/x86/kernel/kprobes/core.c | 2 +- drivers/misc/lkdtm/cfi.c | 2 +- kernel/module/tree_lookup.c | 2 +- kernel/configs/hardening.config | 2 +- 74 files changed, 569 insertions(+), 118 deletions(-) create mode 100644 scripts/kconfig/tests/err_transitional/Kconfig create mode 100644 scripts/kconfig/tests/transitional/Kconfig create mode 100644 scripts/kconfig/tests/err_transitional/__init__.py create mode 100644 scripts/kconfig/tests/err_transitional/expected_stderr create mode 100644 scripts/kconfig/tests/transitional/__init__.py create mode 100644 scripts/kconfig/tests/transitional/expected_config create mode 100644 scripts/kconfig/tests/transitional/initial_config
Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH v2 1/9 compiler_types.h: Move __nocfi out of compiler-specific header
Prepare for GCC KCFI support and move the __nocfi attribute from compiler-clang.h to compiler_types.h. This was already gated by CONFIG_CFI_CLANG, so this remains safe for non-KCFI GCC builds.
---
Cc: Nathan Chancellor <[email protected]>
Cc: Nick Desaulniers <[email protected]>
Cc: Bill Wendling <[email protected]>
Cc: Justin Stitt <[email protected]>
Cc: Miguel Ojeda <[email protected]>
Cc: Marco Elver <[email protected]>
Cc: Przemek Kitszel <[email protected]>
Cc: Ramon de C Valle <[email protected]>
Cc: <[email protected]>
--- include/linux/compiler-clang.h | 5 ----- include/linux/compiler_types.h | 4 +++- 2 files changed, 3 insertions(+), 6 deletions(-)
include/linux/compiler-clang.h +0 -5
@@ -96,11 +96,6 @@# define __noscs __attribute__((__no_sanitize__("shadow-call-stack")))#endif -#if __has_feature (kcfi) -/* Disable CFI checking inside a function. */ -#define __nocfi __attribute__((__no_sanitize__("kcfi"))) -#endif -/* * Turn individual warnings and errors on and off locally, depending * on version.
include/linux/compiler_types.h +3 -1
@@ -432,7 +432,9 @@ struct ftrace_likely_data {# define __noscs#endif -#ifndef __nocfi +#if defined(CONFIG_CFI_CLANG ) +# define __nocfi __attribute__((__no_sanitize__("kcfi"))) +#else # define __nocfi#endif
Signature · 1 line
2.34.1
Re: [PATCH v2 1/9] compiler_types.h: Move __nocfi out of compiler-specific header
Quoted 6 lines · Kees Cook
Prepare for GCC KCFI support and move the
__nocfiattribute fromcompiler-clang.htocompiler_types.h. This was already gated byCONFIG_CFI_CLANG, so this remains safe for non-KCFI GCC builds.Signed-off-by Kees Cook <[email protected]>---
I reviewed this on v1:
https://lore.kernel.org/20250827194657.GA3572128@ax162/
but just to make sure it sticks :)
Quoted 39 lines
--- include/linux/compiler-clang.h | 5 ----- include/linux/compiler_types.h | 4 +++- 2 files changed, 3 insertions(+), 6 deletions(-)include/linux/compiler-clang.h +0
-5@@ -96,11 +96,6 @@# define __noscs __attribute__((__no_sanitize__("shadow-call-stack")))#endif -#if __has_feature (kcfi) -/* Disable CFI checking inside a function. */ -#define __nocfi __attribute__((__no_sanitize__("kcfi"))) -#endif -/* * Turn individual warnings and errors on and off locally, depending * on version. include/linux/compiler_types.h +3
-1@@ -432,7 +432,9 @@ struct ftrace_likely_data {# define __noscs#endif -#ifndef __nocfi +#if defined(CONFIG_CFI_CLANG ) +# define __nocfi __attribute__((__no_sanitize__("kcfi"))) +#else # define __nocfi#endif Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH v2 2/9 x86/traps: Clarify KCFI instruction layout
In reply to Kees CookJust a nit-picky change to the KCFI indirect call check instruction documentation. The addl offset isn't always -4 (it depends on patchable function entry configuration).
---
Cc: Peter Zijlstra <[email protected]>
--- arch/x86/kernel/cfi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kernel/cfi.c +1 -1
@@ -27,7 +27,7 @@ static bool decode_cfi_insn(struct pt_regs *regs, unsigned long *target,* for indirect call checks: * * movl -<id>, %r10d ; 6 bytes -* addl -4(%reg), %r10d ; 4 bytes +* addl -<pos>(%reg), %r10d; 4 bytes * je .Ltmp1 ; 2 bytes * ud2 ; <- regs->ip * .Ltmp1:
Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH v2 3/9 x86/cfi: Document the "cfi=" bootparam options
In reply to Kees CookThe kernel-parameters.txt didn't have a section for the cfi= options. Add it.
---
Cc: Jonathan Corbet <[email protected]>
Cc: "Paul E. McKenney" <[email protected]>
Cc: Randy Dunlap <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: <[email protected]>
--- Documentation/admin-guide/kernel-parameters.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
Documentation/admin-guide/kernel-parameters.txt +17 -0
@@ -608,6 +608,23 @@ ccw_timeout_log [S390] See Documentation/arch/s390/common_io.rst for details. + cfi= [X86-64] Set Control Flow Integrity checking features + when CONFIG_FINEIBT is enabled. + Format: feature[,feature...] + Default: auto + + auto: Use FineIBT if IBT available, otherwise kCFI. + Under FineIBT, enable "paranoid" mode when + FRED is not available. + off: Turn off CFI checking. + kcfi: Use kCFI (disable FineIBT). + fineibt: Use FineIBT (even if IBT not available). + norand: Do not re-randomize CFI hashes. + paranoid: Add caller hash checking under FineIBT. + bhi: Enable register poisoning to stop speculation + across FineIBT. (Disabled by default.) + warn: Do not enforce CFI checking: warn only. + cgroup_disable= [KNL] Disable a particular controller or optional feature Format: {name of the controller(s) or feature(s) to disable} The effects of cgroup_disable=foo are:
Signature · 1 line
2.34.1
Re: [PATCH v2 3/9] x86/cfi: Document the "cfi=" bootparam options
Quoted 5 lines · Kees Cook
The kernel-parameters.txt didn't have a section for the cfi= options. Add it.
Signed-off-by Kees Cook <[email protected]>---
Quoted 35 lines
--- Documentation/admin-guide/kernel-parameters.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)Documentation/admin-guide/kernel-parameters.txt +17
-0@@ -608,6 +608,23 @@ ccw_timeout_log [S390] See Documentation/arch/s390/common_io.rst for details. + cfi= [X86-64] Set Control Flow Integrity checking features + when CONFIG_FINEIBT is enabled. + Format: feature[,feature...] + Default: auto + + auto: Use FineIBT if IBT available, otherwise kCFI. + Under FineIBT, enable "paranoid" mode when + FRED is not available. + off: Turn off CFI checking. + kcfi: Use kCFI (disable FineIBT). + fineibt: Use FineIBT (even if IBT not available). + norand: Do not re-randomize CFI hashes. + paranoid: Add caller hash checking under FineIBT. + bhi: Enable register poisoning to stop speculation + across FineIBT. (Disabled by default.) + warn: Do not enforce CFI checking: warn only. + cgroup_disable= [KNL] Disable a particular controller or optional feature Format: {name of the controller(s) or feature(s) to disable} The effects of cgroup_disable=foo are:Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH v2 4/9 x86/cfi: Standardize on common "CFI:" prefix for CFI reports
In reply to Kees CookUse a regular "CFI:" prefix for CFI reports during alternatives setup, including reporting when nothing has happened (i.e. CONFIG_FINEIBT=n).
---
Cc: Peter Zijlstra <[email protected]>
--- arch/x86/kernel/alternative.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
arch/x86/kernel/alternative.c +10 -7
@@ -1266,26 +1266,26 @@ static __init int cfi_parse_cmdline(char *str) }else if (!strcmp (str,"norand" )) { cfi_rand = false; }else if (!strcmp (str,"warn" )) { -pr_alert ("CFI mismatch non-fatal!\n" ); +pr_alert ("CFI: mismatch non-fatal!\n" ); cfi_warn = true; }else if (!strcmp (str,"paranoid" )) {if (cfi_mode ==CFI_FINEIBT ) { cfi_paranoid = true; }else { -pr_err ("Ignoring paranoid; depends on fineibt.\n" ); +pr_err ("CFI: ignoring paranoid; depends on fineibt.\n" ); } }else if (!strcmp (str,"bhi" )) {#ifdef CONFIG_FINEIBT_BHI if (cfi_mode ==CFI_FINEIBT ) { cfi_bhi = true; }else { -pr_err ("Ignoring bhi; depends on fineibt.\n" ); +pr_err ("CFI: ignoring bhi; depends on fineibt.\n" ); }#else -pr_err ("Ignoring bhi; depends on FINEIBT_BHI=y.\n" ); +pr_err ("CFI: ignoring bhi; depends on FINEIBT_BHI=y.\n" );#endif }else { -pr_err ("Ignoring unknown cfi option (%s)." , str); +pr_err ("CFI: Ignoring unknown option (%s)." , str); } str = next;
@@ -1757,7 +1757,7 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,switch (cfi_mode) {case CFI_OFF :if (builtin) -pr_info ("Disabling CFI\n" ); +pr_info ("CFI: disabled\n" );return ;case CFI_KCFI :
@@ -1766,7 +1766,8 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline, goto err;if (builtin) -pr_info ("Using kCFI\n" ); +pr_info ("CFI: Using %sretpoline kCFI\n" , + cfi_rand ?"rehashed " :"" );return ;case CFI_FINEIBT :
@@ -2005,6 +2006,8 @@ bool decode_fineibt_insn(struct pt_regs *regs, unsigned long *target, u32 *type)static void __apply_fineibt (s32 *start_retpoline,s32 *end_retpoline,s32 *start_cfi,s32 *end_cfi,bool builtin) { +if (IS_ENABLED (CONFIG_CFI ) && builtin) +pr_info ("CFI: Using standard kCFI\n" ); }#ifdef CONFIG_X86_KERNEL_IBT
Signature · 1 line
2.34.1
Re: [PATCH v2 4/9] x86/cfi: Standardize on common "CFI:" prefix for CFI reports
Quoted 5 lines · Kees Cook
Use a regular "CFI:" prefix for CFI reports during alternatives setup, including reporting when nothing has happened (i.e.
CONFIG_FINEIBT=n).Signed-off-by Kees Cook <[email protected]>---
Obviously minor but I had pointed out on v1 that there appears to be some inconsistency within the diff around capitalization, "ignoring" vs. "Ignoring".
Quoted 71 lines
--- arch/x86/kernel/alternative.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)arch/x86/kernel/alternative.c +10
-7@@ -1266,26 +1266,26 @@ static __init int cfi_parse_cmdline(char *str) }else if (!strcmp (str,"norand" )) { cfi_rand = false; }else if (!strcmp (str,"warn" )) { -pr_alert ("CFI mismatch non-fatal!\n" ); +pr_alert ("CFI: mismatch non-fatal!\n" ); cfi_warn = true; }else if (!strcmp (str,"paranoid" )) {if (cfi_mode ==CFI_FINEIBT ) { cfi_paranoid = true; }else { -pr_err ("Ignoring paranoid; depends on fineibt.\n" ); +pr_err ("CFI: ignoring paranoid; depends on fineibt.\n" ); } }else if (!strcmp (str,"bhi" )) {#ifdef CONFIG_FINEIBT_BHI if (cfi_mode ==CFI_FINEIBT ) { cfi_bhi = true; }else { -pr_err ("Ignoring bhi; depends on fineibt.\n" ); +pr_err ("CFI: ignoring bhi; depends on fineibt.\n" ); }#else -pr_err ("Ignoring bhi; depends on FINEIBT_BHI=y.\n" ); +pr_err ("CFI: ignoring bhi; depends on FINEIBT_BHI=y.\n" );#endif }else { -pr_err ("Ignoring unknown cfi option (%s)." , str); +pr_err ("CFI: Ignoring unknown option (%s)." , str); } str = next;@@ -1757,7 +1757,7 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,switch (cfi_mode) {case CFI_OFF :if (builtin) -pr_info ("Disabling CFI\n" ); +pr_info ("CFI: disabled\n" );return ;case CFI_KCFI :@@ -1766,7 +1766,8 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline, goto err;if (builtin) -pr_info ("Using kCFI\n" ); +pr_info ("CFI: Using %sretpoline kCFI\n" , + cfi_rand ?"rehashed " :"" );return ;case CFI_FINEIBT :@@ -2005,6 +2006,8 @@ bool decode_fineibt_insn(struct pt_regs *regs, unsigned long *target, u32 *type)static void __apply_fineibt (s32 *start_retpoline,s32 *end_retpoline,s32 *start_cfi,s32 *end_cfi,bool builtin) { +if (IS_ENABLED (CONFIG_CFI ) && builtin) +pr_info ("CFI: Using standard kCFI\n" ); }#ifdef CONFIG_X86_KERNEL_IBT Signature · 1 line
2.34.1
Kees Cook
maintainerRe: [PATCH v2 4/9] x86/cfi: Standardize on common "CFI:" prefix for CFI reports
Quoted 4 lines · Nathan Chancellor
Quoted 3 lines · Kees Cook
Use a regular "CFI:" prefix for CFI reports during alternatives setup, including reporting when nothing has happened (i.e.
CONFIG_FINEIBT=n).
Quoted 8 lines
Quoted 2 lines
Signed-off-by Kees Cook <[email protected]>---
Reviewed-by Nathan Chancellor <[email protected]>Obviously minor but I had pointed out on v1 that there appears to be some inconsistency within the diff around capitalization, "ignoring" vs. "Ignoring".
Oops! Sorry, I've fixed that locally now.
Signature · 1 line
Kees Cook
Kees Cook
maintainerPATCH v2 5/9 x86/cfi: Add "debug" option to "cfi=" bootparam
In reply to Kees CookAdd "debug" option for "cfi=" bootparam to get details on early CFI initialization steps so future Kees can find breakage easier.
---
Cc: Peter Zijlstra <[email protected]>
--- .../admin-guide/kernel-parameters.txt | 1 + arch/x86/kernel/alternative.c | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+)
Documentation/admin-guide/kernel-parameters.txt +1 -0
@@ -624,6 +624,7 @@ bhi: Enable register poisoning to stop speculation across FineIBT. (Disabled by default.) warn: Do not enforce CFI checking: warn only. + debug: Report CFI initialization details. cgroup_disable= [KNL] Disable a particular controller or optional feature Format: {name of the controller(s) or feature(s) to disable}
arch/x86/kernel/alternative.c +23 -0
@@ -1177,6 +1177,7 @@ void __init_or_module apply_seal_endbr(s32 *start, s32 *end) { }#endif enum cfi_mode cfi_mode__ro_after_init = __CFI_DEFAULT; +static bool cfi_debug__ro_after_init ;#ifdef CONFIG_FINEIBT_BHI bool cfi_bhi__ro_after_init = false;
@@ -1259,6 +1260,8 @@ static __init int cfi_parse_cmdline(char *str) }else if (!strcmp (str,"off" )) { cfi_mode =CFI_OFF ; cfi_rand = false; + }else if (!strcmp (str,"debug" )) { + cfi_debug = true; }else if (!strcmp (str,"kcfi" )) { cfi_mode =CFI_KCFI ; }else if (!strcmp (str,"fineibt" )) {
@@ -1734,6 +1737,8 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,* rewrite them. This disables all CFI. If this succeeds but any of the * later stages fails, we're without CFI. */ +if (cfi_debug) +pr_info ("CFI: disabling all indirect call checking\n" ); ret =cfi_disable_callers (start_retpoline, end_retpoline);if (ret) goto err;
@@ -1744,14 +1749,23 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline, cfi_bpf_hash =cfi_rehash (cfi_bpf_hash); cfi_bpf_subprog_hash =cfi_rehash (cfi_bpf_subprog_hash); } +if (cfi_debug) +pr_info ("CFI: cfi_seed: 0x%08x\n" , cfi_seed); +if (cfi_debug) +pr_info ("CFI: rehashing all preambles\n" ); ret =cfi_rand_preamble (start_cfi, end_cfi);if (ret) goto err; +if (cfi_debug) +pr_info ("CFI: rehashing all indirect calls\n" ); ret =cfi_rand_callers (start_retpoline, end_retpoline);if (ret) goto err; + }else { +if (cfi_debug) +pr_info ("CFI: rehashing disabled\n" ); }switch (cfi_mode) {
@@ -1761,6 +1775,8 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,return ;case CFI_KCFI : +if (cfi_debug) +pr_info ("CFI: enabling all indirect call checking\n" ); ret =cfi_enable_callers (start_retpoline, end_retpoline);if (ret) goto err;
@@ -1771,17 +1787,23 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,return ;case CFI_FINEIBT : +if (cfi_debug) +pr_info ("CFI: adding FineIBT to all preambles\n" );/* place the FineIBT preamble at func()-16 */ ret =cfi_rewrite_preamble (start_cfi, end_cfi);if (ret) goto err;/* rewrite the callers to target func()-16 */ +if (cfi_debug) +pr_info ("CFI: rewriting indirect call sites to use FineIBT\n" ); ret =cfi_rewrite_callers (start_retpoline, end_retpoline);if (ret) goto err;/* now that nobody targets func()+0, remove ENDBR there */ +if (cfi_debug) +pr_info ("CFI: removing old endbr insns\n" );cfi_rewrite_endbr (start_cfi, end_cfi);if (builtin) {
@@ -2324,6 +2346,7 @@ void __init alternative_instructions(void)__apply_fineibt (__retpoline_sites, __retpoline_sites_end, __cfi_sites, __cfi_sites_end, true); + cfi_debug = false;/* * Rewrite the retpolines, must be done before alternatives since
Signature · 1 line
2.34.1
Peter Zijlstra
maintainerRe: [PATCH v2 5/9] x86/cfi: Add "debug" option to "cfi=" bootparam
Quoted 10 lines · Kees Cook
arch/x86/kernel/alternative.c +2
-0@@ -1734,6 +1737,8 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,* rewrite them. This disables all CFI. If this succeeds but any of the * later stages fails, we're without CFI. */ +if (cfi_debug) +pr_info ("CFI: disabling all indirect call checking\n" ); ret =cfi_disable_callers (start_retpoline, end_retpoline);if (ret) goto err;
arch/x86/kernel/alternative.c static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline, · line 1756
Quoted 8 lines
arch/x86/kernel/alternative.c +4
-0@@ -1744,14 +1749,23 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline, cfi_bpf_hash =cfi_rehash (cfi_bpf_hash); cfi_bpf_subprog_hash =cfi_rehash (cfi_bpf_subprog_hash); } +if (cfi_debug) +pr_info ("CFI: cfi_seed: 0x%08x\n" , cfi_seed); +if (cfi_debug) +pr_info ("CFI: rehashing all preambles\n" );
So this repeated if() bugs the heck out of me ... :-)
What would you prefer, this:
if (cfi_debug) {
pr_info("CFI: cfi_seed: 0x%08x\n", cfi_seed);
pr_info("CFI: rehashing all preambles\n");
}or something like:
#define pr_cfi_debug(X...) if (cfi_debug) pr_info(X)
pr_cfi_debug("CFI: cfi_seed: 0x%08x\n", cfi_seed);
pr_cfi_debug("CFI: rehashing all preambles\n");?
Quoted 16 lines
arch/x86/kernel/alternative.c +5
-0ret =cfi_rand_preamble (start_cfi, end_cfi);if (ret) goto err; +if (cfi_debug) +pr_info ("CFI: rehashing all indirect calls\n" ); ret =cfi_rand_callers (start_retpoline, end_retpoline);if (ret) goto err; + }else { +if (cfi_debug) +pr_info ("CFI: rehashing disabled\n" ); }switch (cfi_mode) {
arch/x86/kernel/alternative.c static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline, · line 1779
Quoted 5 lines
arch/x86/kernel/alternative.c +2
-0@@ -1761,6 +1775,8 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,return ;case CFI_KCFI : +if (cfi_debug) +pr_info ("CFI: enabling all indirect call checking\n" );
This should be "CFI: re-enabling all..." I suppose, to better match the earlier "CFI: disabling all ..." message.
Quoted 35 lines
arch/x86/kernel/alternative.c +7
-0ret =cfi_enable_callers (start_retpoline, end_retpoline);if (ret) goto err;@@ -1771,17 +1787,23 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,return ;case CFI_FINEIBT : +if (cfi_debug) +pr_info ("CFI: adding FineIBT to all preambles\n" );/* place the FineIBT preamble at func()-16 */ ret =cfi_rewrite_preamble (start_cfi, end_cfi);if (ret) goto err;/* rewrite the callers to target func()-16 */ +if (cfi_debug) +pr_info ("CFI: rewriting indirect call sites to use FineIBT\n" ); ret =cfi_rewrite_callers (start_retpoline, end_retpoline);if (ret) goto err;/* now that nobody targets func()+0, remove ENDBR there */ +if (cfi_debug) +pr_info ("CFI: removing old endbr insns\n" );cfi_rewrite_endbr (start_cfi, end_cfi);if (builtin) {@@ -2324,6 +2346,7 @@ void __init alternative_instructions(void)__apply_fineibt (__retpoline_sites, __retpoline_sites_end, __cfi_sites, __cfi_sites_end, true); + cfi_debug = false;/* * Rewrite the retpolines, must be done before alternatives since
Kees Cook
maintainerPATCH v2 6/9 x86/cfi: Remove __noinitretpoline and __noretpoline
In reply to Kees CookCommit 66f793099a63 ("x86/retpoline: Avoid retpolines for built-in __init functions") disabled retpolines in __init sections (__noinitretpoline) as a precaution against potential issues with retpolines in early boot, but it has not been a problem in practice (i.e. see Clang below).
Commit 87358710c1fb ("x86/retpoline: Support retpoline builds with Clang") narrowed this to only GCC, as Clang doesn't have per-function control over retpoline emission. As such, Clang has been booting with retpolines in __init since retpoline support was introduced.
Clang KCFI has been instrumenting __init since CFI was introduced.
With the introduction of KCFI for GCC, KCFI instrumentation with retpolines disabled means that objtool does not construct .retpoline_sites section entries for the non-retpoline KCFI calls. At boot, the KCFI rehashing code, via __apply_fineibt(), misses all __init KCFI calls (since they are not retpolines), resulting in immediate hash mismatches:
all preambles are rehashed (via .cfi_sites) and none of the __init call sites are rehashed.
Remove __noinitretpoline since it provides no meaningful utility and creates problems with CFI. Additionally remove __noretpoline since it is now unused.
Alternatively, cfi_rand_callers() could walk the .kcfi_traps section which is exactly the list of KCFI instrumentation sites. But it seems better to have as few differences in common instruction sequences between compilers as possible, so better to remove the special handling of retpolines in __init for GCC.
---
Cc: Peter Zijlstra <[email protected]>
Cc: David Woodhouse <[email protected]>
--- include/linux/compiler-gcc.h | 4 ---- include/linux/init.h | 8 -------- 2 files changed, 12 deletions(-)
include/linux/compiler-gcc.h +0 -4
@@ -35,10 +35,6 @@ (typeof (ptr)) (__ptr + (off)); \ }) -#ifdef CONFIG_MITIGATION_RETPOLINE -#define __noretpoline __attribute__((__indirect_branch__("keep"))) -#endif -#if defined(LATENT_ENTROPY_PLUGIN ) && !defined(__CHECKER__)#define __latent_entropy __attribute__((latent_entropy))#endif
include/linux/init.h +0 -8
@@ -7,13 +7,6 @@#include <linux/stringify.h> #include <linux/types.h> -/* Built-in __init functions needn't be compiled with retpoline */ -#if defined(__noretpoline) && !defined(MODULE ) -#define __noinitretpoline __noretpoline -#else -#define __noinitretpoline -#endif -/* These macros are used to mark some functions or * initialized data (doesn't apply to uninitialized data) * as `initialization' functions. The kernel can take this
@@ -50,7 +43,6 @@/* These are for everybody (although not all archs will actually discard it in modules) */ #define __init __section(".init.text") __cold __latent_entropy \ - __noinitretpoline \ __no_kstack_erase#define __initdata __section(".init.data")#define __initconst __section(".init.rodata")
Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH v2 7/9 kconfig: Add transitional symbol attribute for migration support
In reply to Kees CookDuring kernel option migrations (e.g. CONFIG_CFI_CLANG to CONFIG_CFI), existing .config files need to maintain backward compatibility while preventing deprecated options from appearing in newly generated configurations. This is challenging with existing Kconfig mechanisms because:
1. Simply removing old options breaks existing .config files.
2. Manually listing an option as "deprecated" leaves it needlessly visible and still writes them to new .config files.
3. Using any method to remove visibility (.e.g no 'prompt', 'if n', etc) prevents the option from being processed at all.
Add a "transitional" attribute that creates symbols which are:
- Processed during configuration (can influence other symbols' defaults)
- Hidden from user menus (no prompts appear)
- Omitted from newly written .config files (gets migrated)
- Restricted to only having help sections (no defaults, selects, etc) making it truly just a "prior value pass-through" option.
The transitional syntax requires a type argument and prevents type redefinition:
config NEW_OPTION
bool "New option"
default OLD_OPTION
config OLD_OPTION
bool
transitional
help
Transitional config for OLD_OPTION migration.
This allows seamless migration: olddefconfig processes existing CONFIG_OLD_OPTION=y settings to enable CONFIG_NEW_OPTION=y, while CONFIG_OLD_OPTION is omitted from newly generated .config files.
Implementation details:
- Parser validates transitional symbols can only have help sections
- Symbol visibility logic updated: usable = (visible != no || transitional)
- Transitional symbols preserve user values during configuration
- Documentation added to show the usage
- Added positive and negative testing via "testconfig" target
---
With help from Claude Code to show me how to navigate the kconfig parser.
--- .../kconfig/tests/err_transitional/Kconfig | 52 +++++++++ scripts/kconfig/tests/transitional/Kconfig | 100 ++++++++++++++++++ scripts/kconfig/expr.h | 1 + scripts/kconfig/lexer.l | 1 + scripts/kconfig/parser.y | 47 ++++++++ scripts/kconfig/symbol.c | 16 ++- .../tests/err_transitional/__init__.py | 14 +++ .../tests/err_transitional/expected_stderr | 7 ++ .../kconfig/tests/transitional/__init__.py | 18 ++++ .../tests/transitional/expected_config | 12 +++ .../kconfig/tests/transitional/initial_config | 16 +++ Documentation/kbuild/kconfig-language.rst | 32 ++++++ 12 files changed, 313 insertions(+), 3 deletions(-) create mode 100644 scripts/kconfig/tests/err_transitional/Kconfig create mode 100644 scripts/kconfig/tests/transitional/Kconfig create mode 100644 scripts/kconfig/tests/err_transitional/__init__.py create mode 100644 scripts/kconfig/tests/err_transitional/expected_stderr create mode 100644 scripts/kconfig/tests/transitional/__init__.py create mode 100644 scripts/kconfig/tests/transitional/expected_config create mode 100644 scripts/kconfig/tests/transitional/initial_config
scripts/kconfig/tests/err_transitional/Kconfig new file +52 -0
@@ -0,0 +1,52 @@ +# SPDX-License-Identifier: GPL-2.0 +# Test that transitional symbols cannot have properties other than help + +config BAD_DEFAULT + bool + transitional + default y + help + This transitional symbol illegally has a default property. + +config BAD_PROMPT + bool + transitional + prompt "Bad prompt" + help + This transitional symbol illegally has a prompt. + +config BAD_SELECT + bool + transitional + select OTHER_SYMBOL + help + This transitional symbol illegally has a select. + +config BAD_IMPLY + bool + transitional + imply OTHER_SYMBOL + help + This transitional symbol illegally has an imply. + +config BAD_DEPENDS + bool + transitional + depends on OTHER_SYMBOL + help + This transitional symbol illegally has a depends. + +config BAD_RANGE + int + transitional + range 1 10 + help + This transitional symbol illegally has a range. + +config BAD_NO_TYPE + transitional + help + This transitional symbol illegally has no type specified. + +config OTHER_SYMBOL + bool
scripts/kconfig/tests/transitional/Kconfig new file +100 -0
100 lines not on this page · raw message
scripts/kconfig/expr.h +1 -0
@@ -145,6 +145,7 @@ struct symbol {#define SYMBOL_CONST 0x0001/* symbol is const */ #define SYMBOL_CHECK 0x0008/* used during dependency checking */ #define SYMBOL_VALID 0x0080/* set when symbol.curr is calculated */ +#define SYMBOL_HIDDEN 0x0100/* symbol is hidden (usable but invisible) */ #define SYMBOL_WRITE 0x0200/* write symbol to file (KCONFIG_CONFIG) */ #define SYMBOL_WRITTEN 0x0800/* track info to avoid double-write to .config */ #define SYMBOL_CHECKED 0x2000/* used during dependency checking */
scripts/kconfig/lexer.l +1 -0
@@ -126,6 +126,7 @@ n [A-Za-z0-9_-] "select" return T_SELECT; "source" return T_SOURCE; "string" return T_STRING; +"transitional" return T_TRANSITIONAL; "tristate" return T_TRISTATE; "visible" return T_VISIBLE; "||" return T_OR;
scripts/kconfig/parser.y +47 -0
71 lines not on this page · raw message
scripts/kconfig/symbol.c +13 -3
@@ -408,6 +408,7 @@ void sym_calc_value(struct symbol *sym)struct symbol_value newval, oldval;struct property *prop;struct menu *choice_menu; +bool usable;if (!sym)return ;
@@ -447,6 +448,13 @@ void sym_calc_value(struct symbol *sym)if (sym->visible != no) sym->flags |=SYMBOL_WRITE ; +/* +* For a symbol to be processed during configuration it needs to +* be either visible or a transitional symbol that is hidden from +* menus and omitted from newly written .config files. +*/ + usable = (sym->visible != no || (sym->flags &SYMBOL_HIDDEN )); +/* set default if recursively called */ sym->curr = newval;
@@ -459,13 +467,15 @@ void sym_calc_value(struct symbol *sym)sym_calc_choice (choice_menu); newval.tri = sym->curr.tri; }else { -if (sym->visible != no) { +if (usable) {/* if the symbol is visible use the user value * if available, otherwise try the default value */ if (sym_has_value (sym)) { +tristate value = (sym->flags &SYMBOL_HIDDEN ) ? + sym->def[S_DEF_USER ].tri : sym->visible; newval.tri =EXPR_AND (sym->def[S_DEF_USER ].tri, - sym->visible); + value); goto calc_newval; } }
@@ -497,7 +507,7 @@ void sym_calc_value(struct symbol *sym)case S_STRING :case S_HEX :case S_INT : -if (sym->visible != no &&sym_has_value (sym)) { +if (usable &&sym_has_value (sym)) { newval.val = sym->def[S_DEF_USER ].val;break ; }
scripts/kconfig/tests/err_transitional/__init__.py new file +14 -0
@@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Test that transitional symbols with invalid properties are rejected. + +Transitional symbols can only have help sections. Any other properties +(default, select, depends, etc.) should cause a parser error. +""" + +def test(conf): + # This should fail with exit code 1 due to invalid transitional symbol + assert conf.olddefconfig() == 1 + + # Check that the error message is about transitional symbols + assert conf.stderr_contains('expected_stderr')
scripts/kconfig/tests/err_transitional/expected_stderr new file +7 -0
@@ -0,0 +1,7 @@ +Kconfig:46:warning: config symbol defined without type +Kconfig:7: error: transitional symbols can only have help sections +Kconfig:14: error: transitional symbols can only have help sections +Kconfig:21: error: transitional symbols can only have help sections +Kconfig:28: error: transitional symbols can only have help sections +Kconfig:32: error: transitional symbols can only have help sections +Kconfig:42: error: transitional symbols can only have help sections
scripts/kconfig/tests/transitional/__init__.py new file +18 -0
@@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0 +""" +Test transitional symbol migration functionality for all Kconfig types. + +This tests that: +- OLD_* options in existing .config cause NEW_* options to be set +- OLD_* options are not written to the new .config file +- NEW_* options appear in the new .config file with correct values +- All Kconfig types work correctly: bool, tristate, string, hex, int +- User-set NEW values take precedence over conflicting OLD transitional values +""" + +def test(conf): + # Run olddefconfig to process the migration with the initial config + assert conf.olddefconfig(dot_config='initial_config') == 0 + + # Check that the configuration matches expected output + assert conf.config_contains('expected_config')
scripts/kconfig/tests/transitional/expected_config new file +12 -0
@@ -0,0 +1,12 @@ +CONFIG_MODULES=y +CONFIG_NEW_BOOL=y +CONFIG_NEW_TRISTATE=m +CONFIG_NEW_STRING="test string" +CONFIG_NEW_HEX=0x1234 +CONFIG_NEW_INT=42 +# CONFIG_NEW_BOOL_PRECEDENCE is not set +CONFIG_NEW_STRING_PRECEDENCE="user value" +CONFIG_NEW_TRISTATE_PRECEDENCE=y +CONFIG_NEW_HEX_PRECEDENCE=0xABCD +CONFIG_NEW_INT_PRECEDENCE=100 +# CONFIG_REGULAR_OPTION is not set
scripts/kconfig/tests/transitional/initial_config new file +16 -0
@@ -0,0 +1,16 @@ +CONFIG_MODULES=y +CONFIG_OLD_BOOL=y +CONFIG_OLD_TRISTATE=m +CONFIG_OLD_STRING="test string" +CONFIG_OLD_HEX=0x1234 +CONFIG_OLD_INT=42 +# CONFIG_NEW_BOOL_PRECEDENCE is not set +CONFIG_OLD_BOOL_PRECEDENCE=y +CONFIG_NEW_STRING_PRECEDENCE="user value" +CONFIG_OLD_STRING_PRECEDENCE="old value" +CONFIG_NEW_TRISTATE_PRECEDENCE=y +CONFIG_OLD_TRISTATE_PRECEDENCE=m +CONFIG_NEW_HEX_PRECEDENCE=0xABCD +CONFIG_OLD_HEX_PRECEDENCE=0x5678 +CONFIG_NEW_INT_PRECEDENCE=100 +CONFIG_OLD_INT_PRECEDENCE=200
Documentation/kbuild/kconfig-language.rst +32 -0
@@ -232,6 +232,38 @@ applicable everywhere (see syntax). enables the third modular state for all config symbols. At most one symbol may have the "modules" option set. +- transitional attribute: "transitional" + This declares the symbol as transitional, meaning it should be processed + during configuration but omitted from newly written .config files. + Transitional symbols are useful for backward compatibility during config + option migrations - they allow olddefconfig to process existing .config + files while ensuring the old option doesn't appear in new configurations. + + A transitional symbol: + - Has no prompt (is not visible to users in menus) + - Is processed normally during configuration (values are read and used) + - Can be referenced in default expressions of other symbols + - Is not written to new .config files + - Cannot have any other properties (it is a pass-through option) + + Example migration from OLD_NAME to NEW_NAME:: + + config NEW_NAME + bool "New option name" + default OLD_NAME + help + This replaces the old CONFIG_OLD_NAME option. + + config OLD_NAME + bool + transitional + help + Transitional config for OLD_NAME to NEW_NAME migration. + + With this setup, existing .config files with "CONFIG_OLD_NAME=y" will + result in "CONFIG_NEW_NAME=y" being set, while CONFIG_OLD_NAME will be + omitted from newly written .config files. + Menu dependencies -----------------
Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH v2 8/9 kcfi: Rename CONFIG_CFI_CLANG to CONFIG_CFI
In reply to Kees CookThe kernel's CFI implementation uses the KCFI ABI specifically, and is not strictly tied to a particular compiler. In preparation for GCC supporting KCFI, rename CONFIG_CFI_CLANG to CONFIG_CFI (along with associated options).
Use new "transitional" Kconfig option for old CONFIG_CFI_CLANG that will enable CONFIG_CFI during olddefconfig.
---
Cc: Sami Tolvanen <[email protected]>
Cc: Linus Walleij <[email protected]>
Cc: Mark Rutland <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Puranjay Mohan <[email protected]>
--- arch/Kconfig | 36 ++++++++++++++++--------- arch/arm/Kconfig | 2 +- arch/arm64/Kconfig | 4 +-- arch/riscv/Kconfig | 6 ++--- arch/x86/Kconfig | 12 ++++----- init/Kconfig | 4 +-- kernel/module/Kconfig | 2 +- lib/Kconfig.debug | 2 +- Makefile | 2 +- arch/arm/mm/Makefile | 2 +- arch/riscv/kernel/Makefile | 2 +- arch/riscv/purgatory/Makefile | 2 +- arch/x86/kernel/Makefile | 2 +- arch/x86/purgatory/Makefile | 2 +- kernel/Makefile | 2 +- arch/riscv/include/asm/cfi.h | 4 +-- arch/x86/include/asm/cfi.h | 4 +-- include/asm-generic/vmlinux.lds.h | 2 +- include/linux/cfi.h | 6 ++--- include/linux/cfi_types.h | 8 +++--- include/linux/compiler.h | 2 +- include/linux/compiler_types.h | 2 +- tools/include/linux/cfi_types.h | 6 ++--- tools/perf/util/include/linux/linkage.h | 2 +- arch/arm/mm/cache-fa.S | 2 +- arch/arm/mm/cache-v4.S | 2 +- arch/arm/mm/cache-v4wb.S | 4 +-- arch/arm/mm/cache-v4wt.S | 2 +- arch/arm/mm/cache-v6.S | 2 +- arch/arm/mm/cache-v7.S | 2 +- arch/arm/mm/cache-v7m.S | 2 +- arch/arm/mm/proc-arm1020.S | 2 +- arch/arm/mm/proc-arm1020e.S | 2 +- arch/arm/mm/proc-arm1022.S | 2 +- arch/arm/mm/proc-arm1026.S | 2 +- arch/arm/mm/proc-arm920.S | 2 +- arch/arm/mm/proc-arm922.S | 2 +- arch/arm/mm/proc-arm925.S | 2 +- arch/arm/mm/proc-arm926.S | 2 +- arch/arm/mm/proc-arm940.S | 2 +- arch/arm/mm/proc-arm946.S | 2 +- arch/arm/mm/proc-feroceon.S | 2 +- arch/arm/mm/proc-mohawk.S | 2 +- arch/arm/mm/proc-xsc3.S | 2 +- arch/arm/mm/tlb-v4.S | 2 +- arch/arm/kernel/hw_breakpoint.c | 2 +- arch/arm64/kernel/debug-monitors.c | 2 +- arch/arm64/kernel/traps.c | 4 +-- arch/arm64/kvm/handle_exit.c | 2 +- arch/arm64/net/bpf_jit_comp.c | 2 +- arch/riscv/net/bpf_jit_comp64.c | 4 +-- arch/x86/kernel/alternative.c | 4 +-- arch/x86/kernel/kprobes/core.c | 2 +- drivers/misc/lkdtm/cfi.c | 2 +- kernel/module/tree_lookup.c | 2 +- kernel/configs/hardening.config | 2 +- 56 files changed, 100 insertions(+), 90 deletions(-)
arch/Kconfig +23 -13
@@ -867,22 +867,26 @@ config PROPELLER_CLANG If unsure, say N. -config ARCH_SUPPORTS_CFI_CLANG +config ARCH_SUPPORTS_CFI bool help - An architecture should select this option if it can support Clang's - Control-Flow Integrity (CFI) checking. + An architecture should select this option if it can support Kernel + Control-Flow Integrity (CFI) checking (-fsanitize=kcfi). config ARCH_USES_CFI_TRAPS bool + help + An architecture should select this option if it requires the + .kcfi_traps section for KCFI trap handling. -config CFI_CLANG - bool "Use Clang's Control Flow Integrity (CFI)" - depends on ARCH_SUPPORTS_CFI_CLANG +config CFI + bool "Use Kernel Control Flow Integrity (kCFI)" + default CFI_CLANG + depends on ARCH_SUPPORTS_CFI depends on $(cc-option,-fsanitize=kcfi) help - This option enables Clang's forward-edge Control Flow Integrity - (CFI) checking, where the compiler injects a runtime check to each + This option enables forward-edge Control Flow Integrity (CFI) + checking, where the compiler injects a runtime check to each indirect function call to ensure the target is a valid function with the correct static type. This restricts possible call targets and makes it more difficult for an attacker to exploit bugs that allow
@@ -891,10 +895,16 @@ config CFI_CLANG https://clang.llvm.org/docs/ControlFlowIntegrity.html +config CFI_CLANG + bool + transitional + help + Transitional config for CFI_CLANG to CFI migration. + config CFI_ICALL_NORMALIZE_INTEGERS bool "Normalize CFI tags for integers" - depends on CFI_CLANG - depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG + depends on CFI + depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS help This option normalizes the CFI tags for integer types so that all integer types of the same size and signedness receive the same CFI
@@ -907,7 +917,7 @@ config CFI_ICALL_NORMALIZE_INTEGERS This option is necessary for using CFI with Rust. If unsure, say N. -config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG +config HAVE_CFI_ICALL_NORMALIZE_INTEGERS def_bool y depends on $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers) # With GCOV/KASAN we need this fix: https://github.com/llvm/llvm-project/pull/104826
@@ -915,7 +925,7 @@ config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC def_bool y - depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG + depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS depends on RUSTC_VERSION >= 107900 # With GCOV/KASAN we need this fix: https://github.com/rust-lang/rust/pull/129373 depends on (RUSTC_LLVM_VERSION >= 190103 && RUSTC_VERSION >= 108200) || \
@@ -923,7 +933,7 @@ config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC config CFI_PERMISSIVE bool "Use CFI in permissive mode" - depends on CFI_CLANG + depends on CFI help When selected, Control Flow Integrity (CFI) violations result in a warning instead of a kernel panic. This option should only be used
arch/arm/Kconfig +1 -1
@@ -38,7 +38,7 @@ config ARM select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT if CPU_V7 select ARCH_NEED_CMPXCHG_1_EMU if CPU_V6 select ARCH_SUPPORTS_ATOMIC_RMW - select ARCH_SUPPORTS_CFI_CLANG + select ARCH_SUPPORTS_CFI select ARCH_SUPPORTS_HUGETLBFS if ARM_LPAE select ARCH_SUPPORTS_PER_VMA_LOCK select ARCH_USE_BUILTIN_BSWAP
arch/arm64/Kconfig +2 -2
@@ -100,7 +100,7 @@ config ARM64 select ARCH_SUPPORTS_SHADOW_CALL_STACK if CC_HAVE_SHADOW_CALL_STACK select ARCH_SUPPORTS_LTO_CLANG if CPU_LITTLE_ENDIAN select ARCH_SUPPORTS_LTO_CLANG_THIN - select ARCH_SUPPORTS_CFI_CLANG + select ARCH_SUPPORTS_CFI select ARCH_SUPPORTS_ATOMIC_RMW select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 select ARCH_SUPPORTS_NUMA_BALANCING
@@ -212,7 +212,7 @@ config ARM64 select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS \ if DYNAMIC_FTRACE_WITH_ARGS && DYNAMIC_FTRACE_WITH_CALL_OPS select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS \ - if (DYNAMIC_FTRACE_WITH_ARGS && !CFI_CLANG && \ + if (DYNAMIC_FTRACE_WITH_ARGS && !CFI && \ (CC_IS_CLANG || !CC_OPTIMIZE_FOR_SIZE)) select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY \ if DYNAMIC_FTRACE_WITH_ARGS
arch/riscv/Kconfig +3 -3
@@ -60,7 +60,7 @@ config RISCV select ARCH_STACKWALK select ARCH_SUPPORTS_ATOMIC_RMW # clang >= 17: https://github.com/llvm/llvm-project/commit/62fa708ceb027713b386c7e0efda994f8bdc27e2 - select ARCH_SUPPORTS_CFI_CLANG if CLANG_VERSION >= 170000 + select ARCH_SUPPORTS_CFI if (!CC_IS_CLANG || CLANG_VERSION >= 170000) select ARCH_SUPPORTS_DEBUG_PAGEALLOC if MMU select ARCH_SUPPORTS_HUGE_PFNMAP if TRANSPARENT_HUGEPAGE select ARCH_SUPPORTS_HUGETLBFS if MMU
@@ -76,7 +76,7 @@ config RISCV select ARCH_USE_MEMTEST select ARCH_USE_QUEUED_RWLOCKS select ARCH_USE_SYM_ANNOTATIONS - select ARCH_USES_CFI_TRAPS if CFI_CLANG + select ARCH_USES_CFI_TRAPS if CFI select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH if MMU select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU select ARCH_WANT_FRAME_POINTERS
@@ -154,7 +154,7 @@ config RISCV select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && MMU && (CLANG_SUPPORTS_DYNAMIC_FTRACE || GCC_SUPPORTS_DYNAMIC_FTRACE) select FUNCTION_ALIGNMENT_4B if HAVE_DYNAMIC_FTRACE && RISCV_ISA_C select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS if HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS - select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS if (DYNAMIC_FTRACE_WITH_ARGS && !CFI_CLANG) + select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS if (DYNAMIC_FTRACE_WITH_ARGS && !CFI) select HAVE_DYNAMIC_FTRACE_WITH_ARGS if HAVE_DYNAMIC_FTRACE select HAVE_FTRACE_GRAPH_FUNC select HAVE_FUNCTION_GRAPH_TRACER if HAVE_DYNAMIC_FTRACE_WITH_ARGS
arch/x86/Kconfig +6 -6
@@ -127,8 +127,8 @@ config X86 select ARCH_SUPPORTS_PAGE_TABLE_CHECK if X86_64 select ARCH_SUPPORTS_NUMA_BALANCING if X86_64 select ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP if NR_CPUS <= 4096 - select ARCH_SUPPORTS_CFI_CLANG if X86_64 - select ARCH_USES_CFI_TRAPS if X86_64 && CFI_CLANG + select ARCH_SUPPORTS_CFI if X86_64 + select ARCH_USES_CFI_TRAPS if X86_64 && CFI select ARCH_SUPPORTS_LTO_CLANG select ARCH_SUPPORTS_LTO_CLANG_THIN select ARCH_SUPPORTS_RT
@@ -2396,11 +2396,11 @@ config FUNCTION_PADDING_CFI default 3 if FUNCTION_ALIGNMENT_8B default 0 -# Basically: FUNCTION_ALIGNMENT - 5*CFI_CLANG +# Basically: FUNCTION_ALIGNMENT - 5*CFI # except Kconfig can't do arithmetic :/ config FUNCTION_PADDING_BYTES int - default FUNCTION_PADDING_CFI if CFI_CLANG + default FUNCTION_PADDING_CFI if CFI default FUNCTION_ALIGNMENT config CALL_PADDING
@@ -2410,7 +2410,7 @@ config CALL_PADDING config FINEIBT def_bool y - depends on X86_KERNEL_IBT && CFI_CLANG && MITIGATION_RETPOLINE + depends on X86_KERNEL_IBT && CFI && MITIGATION_RETPOLINE select CALL_PADDING config FINEIBT_BHI
@@ -2427,7 +2427,7 @@ config CALL_THUNKS config PREFIX_SYMBOLS def_bool y - depends on CALL_PADDING && !CFI_CLANG + depends on CALL_PADDING && !CFI menuconfig CPU_MITIGATIONS bool "Mitigations for CPU vulnerabilities"
init/Kconfig +2 -2
@@ -2063,8 +2063,8 @@ config RUST depends on !GCC_PLUGIN_RANDSTRUCT depends on !RANDSTRUCT depends on !DEBUG_INFO_BTF || (PAHOLE_HAS_LANG_EXCLUDE && !LTO) - depends on !CFI_CLANG || HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC - select CFI_ICALL_NORMALIZE_INTEGERS if CFI_CLANG + depends on !CFI || HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC + select CFI_ICALL_NORMALIZE_INTEGERS if CFI depends on !CALL_PADDING || RUSTC_VERSION >= 108100 depends on !KASAN_SW_TAGS depends on !(MITIGATION_RETHUNK && KASAN) || RUSTC_VERSION >= 108300
kernel/module/Kconfig +1 -1
@@ -460,6 +460,6 @@ config UNUSED_KSYMS_WHITELIST config MODULES_TREE_LOOKUP def_bool y - depends on PERF_EVENTS || TRACING || CFI_CLANG + depends on PERF_EVENTS || TRACING || CFI endif # MODULES
lib/Kconfig.debug +1 -1
@@ -2894,7 +2894,7 @@ config FORTIFY_KUNIT_TEST config LONGEST_SYM_KUNIT_TEST tristate "Test the longest symbol possible" if !KUNIT_ALL_TESTS depends on KUNIT && KPROBES - depends on !PREFIX_SYMBOLS && !CFI_CLANG && !GCOV_KERNEL + depends on !PREFIX_SYMBOLS && !CFI && !GCOV_KERNEL default KUNIT_ALL_TESTS help Tests the longest symbol possible
Makefile +1 -1
@@ -1020,7 +1020,7 @@ KBUILD_AFLAGS += -fno-lto export CC_FLAGS_LTO endif -ifdef CONFIG_CFI_CLANG +ifdef CONFIG_CFI CC_FLAGS_CFI := -fsanitize=kcfi ifdef CONFIG_CFI_ICALL_NORMALIZE_INTEGERS CC_FLAGS_CFI += -fsanitize-cfi-icall-experimental-normalize-integers
arch/arm/mm/Makefile +1 -1
@@ -89,7 +89,7 @@ obj-$(CONFIG_CPU_V6) += proc-v6.o obj-$(CONFIG_CPU_V6K) += proc-v6.o obj-$(CONFIG_CPU_V7) += proc-v7.o proc-v7-bugs.o obj-$(CONFIG_CPU_V7M) += proc-v7m.o -obj-$(CONFIG_CFI_CLANG) += proc.o +obj-$(CONFIG_CFI) += proc.o obj-$(CONFIG_OUTER_CACHE) += l2c-common.o obj-$(CONFIG_CACHE_B15_RAC) += cache-b15-rac.o
arch/riscv/kernel/Makefile +1 -1
@@ -113,7 +113,7 @@ obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o -obj-$(CONFIG_CFI_CLANG) += cfi.o +obj-$(CONFIG_CFI) += cfi.o obj-$(CONFIG_EFI) += efi.o obj-$(CONFIG_COMPAT) += compat_syscall_table.o
arch/riscv/purgatory/Makefile +1 -1
@@ -71,7 +71,7 @@ ifdef CONFIG_STACKPROTECTOR_STRONG PURGATORY_CFLAGS_REMOVE += -fstack-protector-strong endif -ifdef CONFIG_CFI_CLANG +ifdef CONFIG_CFI PURGATORY_CFLAGS_REMOVE += $(CC_FLAGS_CFI) endif
arch/x86/kernel/Makefile +1 -1
@@ -148,7 +148,7 @@ obj-$(CONFIG_UNWINDER_ORC) += unwind_orc.o obj-$(CONFIG_UNWINDER_FRAME_POINTER) += unwind_frame.o obj-$(CONFIG_UNWINDER_GUESS) += unwind_guess.o -obj-$(CONFIG_CFI_CLANG) += cfi.o +obj-$(CONFIG_CFI) += cfi.o obj-$(CONFIG_CALL_THUNKS) += callthunks.o
arch/x86/purgatory/Makefile +1 -1
@@ -57,7 +57,7 @@ ifdef CONFIG_MITIGATION_RETPOLINE PURGATORY_CFLAGS_REMOVE += $(RETPOLINE_CFLAGS) endif -ifdef CONFIG_CFI_CLANG +ifdef CONFIG_CFI PURGATORY_CFLAGS_REMOVE += $(CC_FLAGS_CFI) endif
kernel/Makefile +1 -1
@@ -122,7 +122,7 @@ obj-$(CONFIG_KCSAN) += kcsan/ obj-$(CONFIG_SHADOW_CALL_STACK) += scs.o obj-$(CONFIG_HAVE_STATIC_CALL) += static_call.o obj-$(CONFIG_HAVE_STATIC_CALL_INLINE) += static_call_inline.o -obj-$(CONFIG_CFI_CLANG) += cfi.o +obj-$(CONFIG_CFI) += cfi.o obj-$(CONFIG_PERF_EVENTS) += events/
arch/riscv/include/asm/cfi.h +2 -2
@@ -11,7 +11,7 @@struct pt_regs ; -#ifdef CONFIG_CFI_CLANG +#ifdef CONFIG_CFI enum bug_trap_type handle_cfi_failure (struct pt_regs *regs);#define __bpfcall#else
@@ -19,6 +19,6 @@ static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs) {return BUG_TRAP_TYPE_NONE ; } -#endif /* CONFIG_CFI_CLANG */ +#endif /* CONFIG_CFI */ #endif /* _ASM_RISCV_CFI_H */
arch/x86/include/asm/cfi.h +2 -2
@@ -113,7 +113,7 @@ extern bhi_thunk __bhi_args_end[];struct pt_regs ; -#ifdef CONFIG_CFI_CLANG +#ifdef CONFIG_CFI enum bug_trap_type handle_cfi_failure (struct pt_regs *regs);#define __bpfcall
@@ -157,7 +157,7 @@ static inline int cfi_get_func_arity(void *func) {return 0 ; } -#endif /* CONFIG_CFI_CLANG */ +#endif /* CONFIG_CFI */ #if HAS_KERNEL_IBT ==1 #define CFI_NOSEAL (x) asm(IBT_NOSEAL(__stringify(x)))
include/asm-generic/vmlinux.lds.h +1 -1
@@ -157,7 +157,7 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG)#define PATCHABLE_DISCARDS *(__patchable_function_entries)#endif -#ifndef CONFIG_ARCH_SUPPORTS_CFI_CLANG +#ifndef CONFIG_ARCH_SUPPORTS_CFI /* * Simply points to ftrace_stub, but with the proper protocol. * Defined by the linker script in linux/vmlinux.lds.h
include/linux/cfi.h +3 -3
@@ -11,7 +11,7 @@#include <linux/module.h> #include <asm/cfi.h> -#ifdef CONFIG_CFI_CLANG +#ifdef CONFIG_CFI extern bool cfi_warn; enum bug_trap_type report_cfi_failure(struct pt_regs *regs, unsigned long addr,
@@ -52,7 +52,7 @@ static inline u32 cfi_get_func_hash(void *func)extern u32 cfi_bpf_hash;extern u32 cfi_bpf_subprog_hash; -#else /* CONFIG_CFI_CLANG */ +#else /* CONFIG_CFI */ static inline int cfi_get_offset (void ) {return 0 ; }static inline u32 cfi_get_func_hash (void *func) {return 0 ; }
@@ -60,7 +60,7 @@ static inline u32 cfi_get_func_hash(void *func) { return 0; }#define cfi_bpf_hash 0U#define cfi_bpf_subprog_hash 0U -#endif /* CONFIG_CFI_CLANG */ +#endif /* CONFIG_CFI */ #ifdef CONFIG_ARCH_USES_CFI_TRAPS bool is_cfi_trap (unsigned long addr);
include/linux/cfi_types.h +4 -4
@@ -8,7 +8,7 @@#ifdef __ASSEMBLY__#include <linux/linkage.h> -#ifdef CONFIG_CFI_CLANG +#ifdef CONFIG_CFI /* * Use the __kcfi_typeid_<function> type identifier symbol to * annotate indirectly called assembly functions. The compiler emits
@@ -29,12 +29,12 @@ #define SYM_TYPED_START(name, linkage, align...) \ SYM_TYPED_ENTRY(name, linkage, align) -#else /* CONFIG_CFI_CLANG */ +#else /* CONFIG_CFI */ #define SYM_TYPED_START(name, linkage, align...) \ SYM_START(name, linkage, align) -#endif /* CONFIG_CFI_CLANG */ +#endif /* CONFIG_CFI */ #ifndef SYM_TYPED_FUNC_START #define SYM_TYPED_FUNC_START (name) \
@@ -43,7 +43,7 @@#else /* __ASSEMBLY__ */ -#ifdef CONFIG_CFI_CLANG +#ifdef CONFIG_CFI #define DEFINE_CFI_TYPE (name, func) \/* \ * Force a reference to the function so the compiler generates \
include/linux/compiler.h +1 -1
@@ -248,7 +248,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,#endif /* __KERNEL__ */ -#if defined(CONFIG_CFI_CLANG ) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO ) +#if defined(CONFIG_CFI ) && !defined(__DISABLE_EXPORTS) && !defined(BUILD_VDSO )/* * Force a reference to the external symbol so the compiler generates * __kcfi_typid.
include/linux/compiler_types.h +1 -1
@@ -432,7 +432,7 @@ struct ftrace_likely_data {# define __noscs#endif -#if defined(CONFIG_CFI_CLANG ) +#if defined(CONFIG_CFI )# define __nocfi __attribute__((__no_sanitize__("kcfi")))#else # define __nocfi
tools/include/linux/cfi_types.h +3 -3
@@ -8,7 +8,7 @@#ifdef __ASSEMBLY__#include <linux/linkage.h> -#ifdef CONFIG_CFI_CLANG +#ifdef CONFIG_CFI /* * Use the __kcfi_typeid_<function> type identifier symbol to * annotate indirectly called assembly functions. The compiler emits
@@ -29,12 +29,12 @@ #define SYM_TYPED_START(name, linkage, align...) \ SYM_TYPED_ENTRY(name, linkage, align) -#else /* CONFIG_CFI_CLANG */ +#else /* CONFIG_CFI */ #define SYM_TYPED_START(name, linkage, align...) \ SYM_START(name, linkage, align) -#endif /* CONFIG_CFI_CLANG */ +#endif /* CONFIG_CFI */ #ifndef SYM_TYPED_FUNC_START #define SYM_TYPED_FUNC_START (name) \
tools/perf/util/include/linux/linkage.h +1 -1
@@ -120,7 +120,7 @@#endif // In the kernel sources (include/linux/cfi_types.h), this has a different -// definition when CONFIG_CFI_CLANG is used, for tools/ just use the !clang +// definition when CONFIG_CFI is used, for tools/ just use the !cfi // definition: #ifndef SYM_TYPED_START #define SYM_TYPED_START(name, linkage, align...) \
arch/arm/mm/cache-fa.S +1 -1
@@ -112,7 +112,7 @@ SYM_FUNC_END(fa_flush_user_cache_range) * - end - virtual end address */ SYM_TYPED_FUNC_START(fa_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b fa_coherent_user_range #endif SYM_FUNC_END(fa_coherent_kern_range)
arch/arm/mm/cache-v4.S +1 -1
@@ -104,7 +104,7 @@ SYM_FUNC_END(v4_coherent_user_range) * - size - region size */ SYM_TYPED_FUNC_START(v4_flush_kern_dcache_area) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b v4_dma_flush_range #endif SYM_FUNC_END(v4_flush_kern_dcache_area)
arch/arm/mm/cache-v4wb.S +2 -2
@@ -136,7 +136,7 @@ SYM_FUNC_END(v4wb_flush_user_cache_range) */ SYM_TYPED_FUNC_START(v4wb_flush_kern_dcache_area) add r1, r0, r1 -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b v4wb_coherent_user_range #endif SYM_FUNC_END(v4wb_flush_kern_dcache_area)
@@ -152,7 +152,7 @@ SYM_FUNC_END(v4wb_flush_kern_dcache_area) * - end - virtual end address */ SYM_TYPED_FUNC_START(v4wb_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b v4wb_coherent_user_range #endif SYM_FUNC_END(v4wb_coherent_kern_range)
arch/arm/mm/cache-v4wt.S +1 -1
@@ -108,7 +108,7 @@ SYM_FUNC_END(v4wt_flush_user_cache_range) * - end - virtual end address */ SYM_TYPED_FUNC_START(v4wt_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b v4wt_coherent_user_range #endif SYM_FUNC_END(v4wt_coherent_kern_range)
arch/arm/mm/cache-v6.S +1 -1
@@ -117,7 +117,7 @@ SYM_FUNC_END(v6_flush_user_cache_range) * - the Icache does not read data from the write buffer */ SYM_TYPED_FUNC_START(v6_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b v6_coherent_user_range #endif SYM_FUNC_END(v6_coherent_kern_range)
arch/arm/mm/cache-v7.S +1 -1
@@ -261,7 +261,7 @@ SYM_FUNC_END(v7_flush_user_cache_range) * - the Icache does not read data from the write buffer */ SYM_TYPED_FUNC_START(v7_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b v7_coherent_user_range #endif SYM_FUNC_END(v7_coherent_kern_range)
arch/arm/mm/cache-v7m.S +1 -1
@@ -286,7 +286,7 @@ SYM_FUNC_END(v7m_flush_user_cache_range) * - the Icache does not read data from the write buffer */ SYM_TYPED_FUNC_START(v7m_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b v7m_coherent_user_range #endif SYM_FUNC_END(v7m_coherent_kern_range)
arch/arm/mm/proc-arm1020.S +1 -1
@@ -203,7 +203,7 @@ SYM_FUNC_END(arm1020_flush_user_cache_range) * - end - virtual end address */ SYM_TYPED_FUNC_START(arm1020_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b arm1020_coherent_user_range #endif SYM_FUNC_END(arm1020_coherent_kern_range)
arch/arm/mm/proc-arm1020e.S +1 -1
@@ -200,7 +200,7 @@ SYM_FUNC_END(arm1020e_flush_user_cache_range) * - end - virtual end address */ SYM_TYPED_FUNC_START(arm1020e_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b arm1020e_coherent_user_range #endif SYM_FUNC_END(arm1020e_coherent_kern_range)
arch/arm/mm/proc-arm1022.S +1 -1
@@ -199,7 +199,7 @@ SYM_FUNC_END(arm1022_flush_user_cache_range) * - end - virtual end address */ SYM_TYPED_FUNC_START(arm1022_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b arm1022_coherent_user_range #endif SYM_FUNC_END(arm1022_coherent_kern_range)
arch/arm/mm/proc-arm1026.S +1 -1
@@ -194,7 +194,7 @@ SYM_FUNC_END(arm1026_flush_user_cache_range) * - end - virtual end address */ SYM_TYPED_FUNC_START(arm1026_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b arm1026_coherent_user_range #endif SYM_FUNC_END(arm1026_coherent_kern_range)
arch/arm/mm/proc-arm920.S +1 -1
@@ -180,7 +180,7 @@ SYM_FUNC_END(arm920_flush_user_cache_range) * - end - virtual end address */ SYM_TYPED_FUNC_START(arm920_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b arm920_coherent_user_range #endif SYM_FUNC_END(arm920_coherent_kern_range)
arch/arm/mm/proc-arm922.S +1 -1
@@ -182,7 +182,7 @@ SYM_FUNC_END(arm922_flush_user_cache_range) * - end - virtual end address */ SYM_TYPED_FUNC_START(arm922_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b arm922_coherent_user_range #endif SYM_FUNC_END(arm922_coherent_kern_range)
arch/arm/mm/proc-arm925.S +1 -1
@@ -229,7 +229,7 @@ SYM_FUNC_END(arm925_flush_user_cache_range) * - end - virtual end address */ SYM_TYPED_FUNC_START(arm925_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b arm925_coherent_user_range #endif SYM_FUNC_END(arm925_coherent_kern_range)
arch/arm/mm/proc-arm926.S +1 -1
@@ -192,7 +192,7 @@ SYM_FUNC_END(arm926_flush_user_cache_range) * - end - virtual end address */ SYM_TYPED_FUNC_START(arm926_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b arm926_coherent_user_range #endif SYM_FUNC_END(arm926_coherent_kern_range)
arch/arm/mm/proc-arm940.S +1 -1
@@ -153,7 +153,7 @@ SYM_FUNC_END(arm940_coherent_kern_range) * - end - virtual end address */ SYM_TYPED_FUNC_START(arm940_coherent_user_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b arm940_flush_kern_dcache_area #endif SYM_FUNC_END(arm940_coherent_user_range)
arch/arm/mm/proc-arm946.S +1 -1
@@ -173,7 +173,7 @@ SYM_FUNC_END(arm946_flush_user_cache_range) * - end - virtual end address */ SYM_TYPED_FUNC_START(arm946_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b arm946_coherent_user_range #endif SYM_FUNC_END(arm946_coherent_kern_range)
arch/arm/mm/proc-feroceon.S +1 -1
@@ -208,7 +208,7 @@ SYM_FUNC_END(feroceon_flush_user_cache_range) */ .align 5 SYM_TYPED_FUNC_START(feroceon_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b feroceon_coherent_user_range #endif SYM_FUNC_END(feroceon_coherent_kern_range)
arch/arm/mm/proc-mohawk.S +1 -1
@@ -163,7 +163,7 @@ SYM_FUNC_END(mohawk_flush_user_cache_range) * - end - virtual end address */ SYM_TYPED_FUNC_START(mohawk_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b mohawk_coherent_user_range #endif SYM_FUNC_END(mohawk_coherent_kern_range)
arch/arm/mm/proc-xsc3.S +1 -1
@@ -223,7 +223,7 @@ SYM_FUNC_END(xsc3_flush_user_cache_range) * it also trashes the mini I-cache used by JTAG debuggers. */ SYM_TYPED_FUNC_START(xsc3_coherent_kern_range) -#ifdef CONFIG_CFI_CLANG /* Fallthrough if !CFI */ +#ifdef CONFIG_CFI /* Fallthrough if !CFI */ b xsc3_coherent_user_range #endif SYM_FUNC_END(xsc3_coherent_kern_range)
arch/arm/mm/tlb-v4.S +1 -1
@@ -52,7 +52,7 @@ SYM_FUNC_END(v4_flush_user_tlb_range) * - start - virtual address (may not be aligned) * - end - virtual address (may not be aligned) */ -#ifdef CONFIG_CFI_CLANG +#ifdef CONFIG_CFI SYM_TYPED_FUNC_START(v4_flush_kern_tlb_range) b .v4_flush_kern_tlb_range SYM_FUNC_END(v4_flush_kern_tlb_range)
arch/arm/kernel/hw_breakpoint.c +1 -1
@@ -904,7 +904,7 @@ static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs)watchpoint_single_step_handler (addr); } -#ifdef CONFIG_CFI_CLANG +#ifdef CONFIG_CFI static void hw_breakpoint_cfi_handler (struct pt_regs *regs) {/*
arch/arm64/kernel/debug-monitors.c +1 -1
@@ -212,7 +212,7 @@ static int call_el1_break_hook(struct pt_regs *regs, unsigned long esr)if (esr_brk_comment (esr) ==BUG_BRK_IMM )return bug_brk_handler (regs, esr); -if (IS_ENABLED (CONFIG_CFI_CLANG ) &&esr_is_cfi_brk (esr)) +if (IS_ENABLED (CONFIG_CFI ) &&esr_is_cfi_brk (esr))return cfi_brk_handler (regs, esr);if (esr_brk_comment (esr) ==FAULT_BRK_IMM )
arch/arm64/kernel/traps.c +2 -2
@@ -1015,7 +1015,7 @@ int bug_brk_handler(struct pt_regs *regs, unsigned long esr)return DBG_HOOK_HANDLED ; } -#ifdef CONFIG_CFI_CLANG +#ifdef CONFIG_CFI int cfi_brk_handler (struct pt_regs *regs,unsigned long esr) {unsigned long target;
@@ -1039,7 +1039,7 @@ int cfi_brk_handler(struct pt_regs *regs, unsigned long esr)arm64_skip_faulting_instruction (regs,AARCH64_INSN_SIZE ); return DBG_HOOK_HANDLED; } -#endif /* CONFIG_CFI_CLANG */ +#endif /* CONFIG_CFI */ int reserved_fault_brk_handler (struct pt_regs *regs,unsigned long esr) {
arch/arm64/kvm/handle_exit.c +1 -1
@@ -545,7 +545,7 @@ void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr,kvm_err ("nVHE hyp BUG at: %s:%u!\n" , file, line); else print_nvhe_hyp_panic("BUG", panic_addr); - }else if (IS_ENABLED (CONFIG_CFI_CLANG ) &&esr_is_cfi_brk (esr)) { + }else if (IS_ENABLED (CONFIG_CFI ) &&esr_is_cfi_brk (esr)) {kvm_nvhe_report_cfi_failure (panic_addr); } else if (IS_ENABLED(CONFIG_UBSAN_KVM_EL2) && ESR_ELx_EC(esr) == ESR_ELx_EC_BRK64 &&
arch/arm64/net/bpf_jit_comp.c +1 -1
@@ -185,7 +185,7 @@ static inline void emit_bti(u32 insn, struct jit_ctx *ctx)static inline void emit_kcfi (u32 hash,struct jit_ctx *ctx) { -if (IS_ENABLED (CONFIG_CFI_CLANG )) +if (IS_ENABLED (CONFIG_CFI ))emit_u32_data (hash, ctx); }
arch/riscv/net/bpf_jit_comp64.c +2 -2
@@ -18,7 +18,7 @@#define RV_MAX_REG_ARGS 8#define RV_FENTRY_NINSNS 2#define RV_FENTRY_NBYTES (RV_FENTRY_NINSNS * 4) -#define RV_KCFI_NINSNS (IS_ENABLED(CONFIG_CFI_CLANG) ? 1 : 0) +#define RV_KCFI_NINSNS (IS_ENABLED(CONFIG_CFI) ? 1 : 0)/* imm that allows emit_imm to emit max count insns */ #define RV_MAX_COUNT_IMM 0x7FFF7FF7FF7FF7FF
@@ -469,7 +469,7 @@ static int emit_call(u64 addr, bool fixed_addr, struct rv_jit_context *ctx)static inline void emit_kcfi (u32 hash,struct rv_jit_context *ctx) { -if (IS_ENABLED (CONFIG_CFI_CLANG )) +if (IS_ENABLED (CONFIG_CFI ))emit (hash, ctx); }
arch/x86/kernel/alternative.c +2 -2
@@ -1170,7 +1170,7 @@ void __init_or_module apply_seal_endbr(s32 *start, s32 *end) { }#ifdef CONFIG_CFI_AUTO_DEFAULT # define __CFI_DEFAULT CFI_AUTO -#elif defined(CONFIG_CFI_CLANG ) +#elif defined(CONFIG_CFI )# define __CFI_DEFAULT CFI_KCFI#else # define __CFI_DEFAULT CFI_OFF
@@ -1183,7 +1183,7 @@ static bool cfi_debug __ro_after_init;bool cfi_bhi__ro_after_init = false;#endif -#ifdef CONFIG_CFI_CLANG +#ifdef CONFIG_CFI u32 cfi_get_func_hash (void *func) {u32 hash;
arch/x86/kernel/kprobes/core.c +1 -1
@@ -339,7 +339,7 @@ static bool can_probe(unsigned long paddr)if (is_exception_insn (&insn))return false; -if (IS_ENABLED (CONFIG_CFI_CLANG )) { +if (IS_ENABLED (CONFIG_CFI )) {/* * The compiler generates the following instruction sequence * for indirect call checks and cfi.c decodes this;
drivers/misc/lkdtm/cfi.c +1 -1
@@ -43,7 +43,7 @@ static void lkdtm_CFI_FORWARD_PROTO(void)lkdtm_indirect_call ((void *)lkdtm_increment_int);pr_err ("FAIL: survived mismatched prototype function call!\n" ); -pr_expected_config (CONFIG_CFI_CLANG ); +pr_expected_config (CONFIG_CFI ); }/*
kernel/module/tree_lookup.c +1 -1
@@ -14,7 +14,7 @@* Use a latched RB-tree for __module_address(); this allows us to use * RCU lookups of the address from any context. * -* This is conditional on PERF_EVENTS || TRACING || CFI_CLANG because those can +* This is conditional on PERF_EVENTS || TRACING || CFI because those can * really hit __module_address() hard by doing a lot of stack unwinding; * potentially from NMI context. */
kernel/configs/hardening.config +1 -1
@@ -94,7 +94,7 @@ CONFIG_SECCOMP_FILTER=y CONFIG_SYN_COOKIES=y # Enable Kernel Control Flow Integrity (currently Clang only). -CONFIG_CFI_CLANG=y +CONFIG_CFI=y # CONFIG_CFI_PERMISSIVE is not set # Attack surface reduction: do not autoload TTY line disciplines.
Signature · 1 line
2.34.1
Kees Cook
maintainerPATCH v2 9/9 ARM: traps: Implement KCFI trap handler for ARM32
In reply to Kees CookARM32 KCFI violations currently show as generic "Oops - undefined instruction" errors, making debugging CFI failures difficult. Add a proper KCFI trap handler similar to the aarch64 implementation to provide clear CFI error messages.
The GCC ARM32 KCFI implementation uses UDF instructions with a specific encoding pattern:
- UDF instruction format: cccc 0111 1111 imm12 1111 imm4
- 16-bit immediate reconstructed from bits 19-8 and 3-0
- KCFI encoding: 0x8000 | (type_reg_num << 5) | (target_reg_num & 31)
- Bit 15: KCFI trap identifier (0x8000)
- Bits 9-5: Type ID register field (0x1F when unavailable)
- Bits 4-0: Target address register number
When the type register field is 0x1F (unavailable due to stack spilling), the handler walks back up to 5 preceding instructions to locate the movw/movt instruction pair that loads the 32-bit type ID, similar to x86 CFI trap reconstruction.
The undef_hook pattern matching includes the KCFI bit requirement to ensure the handler is only called for KCFI violations, not arbitrary UDF instructions.
---
Cc: "Russell King (Oracle)" <[email protected]>
Cc: Zhen Lei <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: "Michał Pecio" <[email protected]>
Cc: Sebastian Andrzej Siewior <[email protected]>
Cc: Sami Tolvanen <[email protected]>
Cc: <[email protected]>
--- arch/arm/kernel/traps.c | 102 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+)
arch/arm/kernel/traps.c +102 -0
@@ -27,6 +27,7 @@#include <linux/sched/task_stack.h> #include <linux/irq.h> #include <linux/vmalloc.h> +#include <linux/cfi.h> #include <linux/atomic.h> #include <asm/cacheflush.h>
@@ -40,6 +41,7 @@#include <asm/stacktrace.h> #include <asm/system_misc.h> #include <asm/opcodes.h> +#include <linux/bitfield.h> static const char *handler[]= {
@@ -685,6 +687,106 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)return 0 ; } +#ifdef CONFIG_CFI +/* +* ARM32 KCFI trap handler. +* UDF instruction format: cccc 0111 1111 imm12 1111 imm4 +* Immediate is reconstructed from bits 19-8 (12 bits) and bits 3-0 (4 bits) +* KCFI immediate encoding: 0x8000 | (0x1F << 5) | (target_reg_num & 31) +* - Bit 15: KCFI trap identifier (0x8000) +* - Bits 9-5: Type ID register field (0x1F when invalid due to stack spilling) +* - Bits 4-0: Target address register number +*/ +#define CFI_UDF_KCFI_BIT BIT(15)/* KCFI identifier bit (0x8000) */ +#define CFI_UDF_IMM_TARGET GENMASK(4, 0)/* Target register (bits 4:0) */ +#define CFI_UDF_IMM_TYPE GENMASK(9, 5)/* Type register (bits 9:5) */ + +/* UDF base pattern with KCFI bit: cond=0xe, 0x7f, xxxx, 1xxx, 0xf, xxxx */ +#define CFI_UDF_IMM_BASE 0xe7f008f0 +#define CFI_UDF_IMM_MASK 0xfff008f0/* Mask for UDF + KCFI bit matching */ + +static int cfi_udf_handler (struct pt_regs *regs,unsigned int instr) +{ +unsigned long target; +u32 target_reg, type_reg, type, imm16; + +/* Reconstruct 16-bit immediate from bits 19-8 and 3-0 */ + imm16 = ((instr >>4 ) &0xfff0 ) | (instr &0x0f ); + + target_reg =FIELD_GET (CFI_UDF_IMM_TARGET , imm16); + type_reg =FIELD_GET (CFI_UDF_IMM_TYPE , imm16); + +if (target_reg >=16 ) { +pr_err ("CFI UDF handler: invalid target register %u\n" , target_reg); +return 1 ; + } + + target = regs->uregs[target_reg]; + +/* Type register field is set to all 1s (0x1F) when invalid due to stack spilling */ +if (type_reg ==0x1F ) { +u32 *pc = (u32 *)regs->ARM_pc; +int i; + + type =0 ; +/* Walk back up to 5 instructions to find movw/movt pair for type ID */ +for (i =1 ; i <=5 ; i++) { +u32 instr_prev =__mem_to_opcode_arm (pc[-i]); + +/* Check for movw: cccc 0011 0000 imm4 Rd imm12 */ +if ((instr_prev &0x0ff00000 ) ==0x03000000 ) { +u32 imm16 = ((instr_prev >>4 ) &0xf000 ) | (instr_prev &0xfff ); + type |= imm16; + } +/* Check for movt: cccc 0011 0100 imm4 Rd imm12 */ +else if ((instr_prev &0x0ff00000 ) ==0x03400000 ) { +u32 imm16 = ((instr_prev >>4 ) &0xf000 ) | (instr_prev &0xfff ); + type |= (imm16 <<16 ); + } + } +if (type ==0 ) +pr_err ("CFI UDF handler: failed to find type value\n" ); + }else { +if (type_reg >=16 ) { +pr_err ("CFI UDF handler: invalid type register %u\n" , type_reg); +return 1 ; + } + + type = regs->uregs[type_reg]; + } + +switch (report_cfi_failure (regs, regs->ARM_pc, &target, type)) { +case BUG_TRAP_TYPE_BUG : +die ("Oops - CFI" , regs,0 ); +break ; +case BUG_TRAP_TYPE_WARN : +break ; +default : +return 1 ; + } + +/* Skip the UDF instruction */ + regs->ARM_pc +=4 ; +return 0 ; +} + +static struct undef_hook cfi_undef_hook = { + .instr_mask =CFI_UDF_IMM_MASK , + .instr_val =CFI_UDF_IMM_BASE , + .cpsr_mask =0 , + .cpsr_val =0 , + .fn = cfi_udf_handler, +}; + +static int __init arm_cfi_init (void ) +{ +register_undef_hook (&cfi_undef_hook); +return 0 ; +} + +early_initcall (arm_cfi_init); +#endif /* CONFIG_CFI */ +#ifdef CONFIG_TLS_REG_EMUL /*
Signature · 1 line
2.34.1
Peter Zijlstra
maintainerQuoted 7 lines · Kees Cook
Kees Cook (9):
compiler_types.h: Move__nocfiout of compiler-specific header x86/traps: Clarify KCFI instruction layout
x86/cfi: Document the "cfi=" bootparam options x86/cfi: Standardize on common "CFI:" prefix for CFI reports x86/cfi: Add "debug" option to "cfi=" bootparam x86/cfi: Remove__noinitretpolineand__noretpoline
So I can take these first 6 patches (and edit that debug patch to un-annoy myself ;-), but I'm thinking this Kconfig stuff:
Quoted 2 lines
kconfig: Add transitional symbol attribute for migration support
kcfi: RenameCONFIG_CFI_CLANGtoCONFIG_CFI
Should perhaps go through the kbuild tree? A
Leaving this:
Quoted 1 line
ARM: traps: Implement KCFI trap handler for ARM32
Can that go independently through the arm tree, or are there dependencies?
Kees Cook
maintainerQuoted 10 lines · Peter Zijlstra
Quoted 7 lines · Kees Cook
Kees Cook (9):
compiler_types.h: Move__nocfiout of compiler-specific header x86/traps: Clarify KCFI instruction layout
x86/cfi: Document the "cfi=" bootparam options x86/cfi: Standardize on common "CFI:" prefix for CFI reports x86/cfi: Add "debug" option to "cfi=" bootparam x86/cfi: Remove__noinitretpolineand__noretpoline
Quoted 2 lines
So I can take these first 6 patches (and edit that debug patch to un-annoy myself ;-), but I'm thinking this
Kconfigstuff:
Sure, yeah. Do you want a v3 for the debug stuff that uses your proposed helper?
Quoted 4 lines
Quoted 2 lines
kconfig: Add transitional symbol attribute for migration support
kcfi: RenameCONFIG_CFI_CLANGtoCONFIG_CFIShould perhaps go through the kbuild tree? A
I had chatted offline with Nathan about this series, and he'd suggested the kconfig change could go with it's first user (the rename). So if you don't want to put it in -tip, I can take it in the hardening tree. (There's no dependencies between these 2 and the first 6.)
Quoted 6 lines
Leaving this:
Quoted 1 line
ARM: traps: Implement KCFI trap handler for ARM32
Can that go independently through the arm tree, or are there dependencies?
I can take this too, assuming ARM folks don't want to snag it. I may, however, wait on it, just to avoid implementing the kernel support before the GCC folks are happy with the arm32 KCFI backend and its UDF encoding, etc.
Thanks for looking at these! :)
-Kees
Signature · 1 line
Kees Cook
Peter Zijlstra
maintainerQuoted 11 lines · Kees Cook
Quoted 10 lines · Peter Zijlstra
Quoted 7 lines · Kees Cook
Kees Cook (9):
compiler_types.h: Move__nocfiout of compiler-specific header x86/traps: Clarify KCFI instruction layout
x86/cfi: Document the "cfi=" bootparam options x86/cfi: Standardize on common "CFI:" prefix for CFI reports x86/cfi: Add "debug" option to "cfi=" bootparam x86/cfi: Remove__noinitretpolineand__noretpoline
Quoted 5 lines
Quoted 2 lines
So I can take these first 6 patches (and edit that debug patch to un-annoy myself ;-), but I'm thinking this
Kconfigstuff:Sure, yeah. Do you want a v3 for the debug stuff that uses your proposed helper?
Nah, already done :-) I just pushed out these 6 and my UDB hackery to queue.git/x86/core. If the robots don't complain, I'll stuff it into tip in a few days.
Quoted 9 lines
Quoted 4 lines
Quoted 2 lines
kconfig: Add transitional symbol attribute for migration support
kcfi: RenameCONFIG_CFI_CLANGtoCONFIG_CFIShould perhaps go through the kbuild tree? A
I had chatted offline with Nathan about this series, and he'd suggested the kconfig change could go with it's first user (the rename). So if you don't want to put it in -tip, I can take it in the hardening tree. (There's no dependencies between these 2 and the first 6.)
So I suppose I can carry them, just to keep the lot together, but then I need an ack from someone that actually knows this Kconfig language stuff :-)
You taking them through the hardening tree also works for em.
Kees Cook
maintainerQuoted 3 lines · Peter Zijlstra
Nah, already done :-) I just pushed out these 6 and my UDB hackery to queue.git/x86/core. If the robots don't complain, I'll stuff it into tip in a few days.
Okay, thanks!
Quoted 5 lines
So I suppose I can carry them, just to keep the lot together, but then I need an ack from someone that actually knows this
Kconfiglanguage stuff :-)You taking them through the hardening tree also works for em.
Assuming Nathan (and Vegard? or other folks from the other thread?) are okay with the kconfig changes, I'll take it via hardening.
Wheee
Signature · 1 line
Kees Cook
Quoted 3 lines · Kees Cook
Assuming Nathan (and Vegard? or other folks from the other thread?) are okay with the kconfig changes, I'll take it via hardening.
I haven't had time to take a proper look, test it etc., so I didn't reply, sorry -- but I am following the thread and I am glad if we have something to easily/properly support this, so thanks for this.
(And sorry for having triggered all this discussion/work -- at least if we get this done it will have been worth it :)
I will leave a quick message about the commit message.
Cheers,
Miguel