hardening: Refresh KCFI options, add some more
Subsystems (3)
PATCH 1/1 hardening: Refresh KCFI options, add some more
Add some stuff that got missed along the way:
- CONFIG_UNWIND_PATCH_PAC_INTO_SCS=y so SCS vs PAC is hardware selectable.
- CONFIG_X86_KERNEL_IBT=y while a default, just be sure.
- CONFIG_CFI_CLANG=y for x86 and arm64. (And disable FINEIBT since it isn't as secure as straight KCFI.)
- CONFIG_PAGE_TABLE_CHECK=y for userspace mapping sanity.
---
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: [email protected]
Cc: "H. Peter Anvin" <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nick Desaulniers <[email protected]>
Cc: Bill Wendling <[email protected]>
Cc: Justin Stitt <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
--- arch/arm64/configs/hardening.config | 5 +++++ arch/x86/configs/hardening.config | 9 +++++++++ kernel/configs/hardening.config | 4 ++++ 3 files changed, 18 insertions(+)
arch/arm64/configs/hardening.config +5 -0
@@ -5,6 +5,7 @@ CONFIG_ARM64_SW_TTBR0_PAN=y # Software Shadow Stack or PAC CONFIG_SHADOW_CALL_STACK=y +CONFIG_UNWIND_PATCH_PAC_INTO_SCS=y # Pointer authentication (ARMv8.3 and later). If hardware actually supports # it, one can turn off CONFIG_STACKPROTECTOR_STRONG with this enabled.
@@ -20,3 +21,7 @@ CONFIG_ARM64_E0PD=y # Available in ARMv8.7 and later. CONFIG_ARM64_EPAN=y + +# Enable Kernel Control Flow Integrity (currently Clang only). +CONFIG_CFI_CLANG=y +# CONFIG_CFI_PERMISSIVE is not set
arch/x86/configs/hardening.config +9 -0
@@ -10,5 +10,14 @@ CONFIG_INTEL_IOMMU_DEFAULT_ON=y CONFIG_INTEL_IOMMU_SVM=y CONFIG_AMD_IOMMU=y +# Enforce CET Indirect Branch Tracking in the kernel. +CONFIG_X86_KERNEL_IBT=y + +# Enable Kernel Control Flow Integrity (currently Clang only), but disable +# weaker FINEIBT landing pads. +CONFIG_CFI_CLANG=y +# CONFIG_CFI_PERMISSIVE is not set +# CONFIG_FINEIBT is not set + # Enable CET Shadow Stack for userspace. CONFIG_X86_USER_SHADOW_STACK=y
kernel/configs/hardening.config +4 -0
@@ -23,6 +23,10 @@ CONFIG_SLAB_FREELIST_HARDENED=y CONFIG_SHUFFLE_PAGE_ALLOCATOR=y CONFIG_RANDOM_KMALLOC_CACHES=y +# Sanity check userspace page table mappings. +CONFIG_PAGE_TABLE_CHECK=y +CONFIG_PAGE_TABLE_CHECK_ENFORCED=y + # Randomize kernel stack offset on syscall entry. CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y
Signature · 1 line
2.34.1
Quoted 5 lines · Kees Cook
Add some stuff that got missed along the way:
-
CONFIG_UNWIND_PATCH_PAC_INTO_SCS=yso SCS vs PAC is hardware selectable.
Quoted 8 lines
-
CONFIG_X86_KERNEL_IBT=ywhile a default, just be sure.-
CONFIG_CFI_CLANG=yfor x86 and arm64. (And disable FINEIBT since it isn't as secure as straight KCFI.)-
CONFIG_PAGE_TABLE_CHECK=yfor userspace mapping sanity.Signed-off-by Kees Cook <[email protected]>
Seems reasonable to me.
One comment below.
Quoted 36 lines
---
Cc: "Gustavo A. R. Silva" <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: [email protected]
Cc: "H. Peter Anvin" <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nick Desaulniers <[email protected]>
Cc: Bill Wendling <[email protected]>
Cc: Justin Stitt <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]--- arch/arm64/configs/hardening.config | 5 +++++ arch/x86/configs/hardening.config | 9 +++++++++ kernel/configs/hardening.config | 4 ++++ 3 files changed, 18 insertions(+)arch/arm64/configs/hardening.config +1
-0@@ -5,6 +5,7 @@ CONFIG_ARM64_SW_TTBR0_PAN=y # Software Shadow Stack or PAC CONFIG_SHADOW_CALL_STACK=y +CONFIG_UNWIND_PATCH_PAC_INTO_SCS=y # Pointer authentication (ARMv8.3 and later). If hardware actually supports # it, one can turn off CONFIG_STACKPROTECTOR_STRONG with this enabled.
arch/arm64/configs/hardening.config CONFIG_ARM64_E0PD=y · line 27
Quoted 7 lines
arch/arm64/configs/hardening.config +4
-0@@ -20,3 +21,7 @@ CONFIG_ARM64_E0PD=y # Available in ARMv8.7 and later. CONFIG_ARM64_EPAN=y + +# Enable Kernel Control Flow Integrity (currently Clang only). +CONFIG_CFI_CLANG=y +# CONFIG_CFI_PERMISSIVE is not set
Should this be a part of kernel/configs/hardening.config because RISC-V supports it (and 32-bit ARM will soon too)?
Quoted 37 lines
arch/x86/configs/hardening.config +9
-0@@ -10,5 +10,14 @@ CONFIG_INTEL_IOMMU_DEFAULT_ON=y CONFIG_INTEL_IOMMU_SVM=y CONFIG_AMD_IOMMU=y +# Enforce CET Indirect Branch Tracking in the kernel. +CONFIG_X86_KERNEL_IBT=y + +# Enable Kernel Control Flow Integrity (currently Clang only), but disable +# weaker FINEIBT landing pads. +CONFIG_CFI_CLANG=y +# CONFIG_CFI_PERMISSIVE is not set +# CONFIG_FINEIBT is not set + # Enable CET Shadow Stack for userspace. CONFIG_X86_USER_SHADOW_STACK=ykernel/configs/hardening.config +4
-0@@ -23,6 +23,10 @@ CONFIG_SLAB_FREELIST_HARDENED=y CONFIG_SHUFFLE_PAGE_ALLOCATOR=y CONFIG_RANDOM_KMALLOC_CACHES=y +# Sanity check userspace page table mappings. +CONFIG_PAGE_TABLE_CHECK=y +CONFIG_PAGE_TABLE_CHECK_ENFORCED=y + # Randomize kernel stack offset on syscall entry. CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=ySignature · 1 line
2.34.1
Quoted 8 lines · Nathan Chancellor
On Fri, Apr 26, 2024 at 03:29:44PM -0700, Kees Cook wrote:
[...]arch/arm64/configs/hardening.config CONFIG_ARM64_E0PD=y · line 27
Quoted 3 lines
arch/arm64/configs/hardening.config +3
-0+# Enable Kernel Control Flow Integrity (currently Clang only). +CONFIG_CFI_CLANG=y +# CONFIG_CFI_PERMISSIVE is not setShould this be a part of
kernel/configs/hardening.configbecause RISC-V supports it (and 32-bit ARM will soon too)?
Probably yes. I was worried it might be "noisy" for archs that don't support it, but frankly if someone is using "make hardening.config" they probably want to know about unsupported options. :)
Signature · 1 line
Kees Cook
Quoted 10 lines · Kees Cook
Quoted 8 lines · Nathan Chancellor
On Fri, Apr 26, 2024 at 03:29:44PM -0700, Kees Cook wrote:
[...]arch/arm64/configs/hardening.config CONFIG_ARM64_E0PD=y · line 27
Quoted 3 lines
arch/arm64/configs/hardening.config +3
-0+# Enable Kernel Control Flow Integrity (currently Clang only). +CONFIG_CFI_CLANG=y +# CONFIG_CFI_PERMISSIVE is not setShould this be a part of
kernel/configs/hardening.configbecause RISC-V supports it (and 32-bit ARM will soon too)?
Quoted 3 lines
Probably yes. I was worried it might be "noisy" for archs that don't support it, but frankly if someone is using "make hardening.config" they probably want to know about unsupported options. :)
It would be potentially noisy as it is currently written since someone building with GCC for arm64 or x86_64 could merge hardening.config into their configuration and they would see CONFIG_CFI_CLANG get enabled by merge_config.sh but on oldconfig or olddefconfig, it would get flipped off again because the toolchain dependencies are not met. Might as well make it architecture agnostic at that point :)
Cheers,
Nathan
Quoted 2 lines · Kees Cook
-
CONFIG_CFI_CLANG=yfor x86 and arm64. (And disable FINEIBT since it isn't as secure as straight KCFI.)
Oi ?
Quoted 6 lines · Peter Zijlstra
Quoted 2 lines · Kees Cook
-
CONFIG_CFI_CLANG=yfor x86 and arm64. (And disable FINEIBT since it isn't as secure as straight KCFI.)Oi ?
Same objection I always had[1]: moving the check into the destination means attacks with control over executable memory contents can just omit the check.
But now that I went to go look I see 0c3e806ec0f9 ("x86/cfi: Add boot time hash randomization") is only enabled under FINEIBT... seems better if that were always enabled...
-Kees
[1] https://lore.kernel.org/all/202210181020.79AF7F7@keescook/
Signature · 1 line
Kees Cook
Quoted 8 lines · Kees Cook
Quoted 6 lines · Peter Zijlstra
Quoted 2 lines · Kees Cook
-
CONFIG_CFI_CLANG=yfor x86 and arm64. (And disable FINEIBT since it isn't as secure as straight KCFI.)Oi ?
Quoted 7 lines
Same objection I always had[1]: moving the check into the destination means attacks with control over executable memory contents can just omit the check.
But now that I went to go look I see
0c3e806ec0f9("x86/cfi: Add boot time hash randomization") is only enabled under FINEIBT... seems better if that were always enabled...
And FINEIBT actually can't be disabled... :|
And as it turns out CFI_CLANG doesn't work at all on v6.9...
[ 0.587220] no CFI hash found at: __call_sites+0x339a8/0x34450 ffffffffac20cef8 00 00 00 00 00 [ 0.588226] WARNING: CPU: 0 PID: 0 at arch/x86/kernel/alternative.c:1182 __apply_fineibt+0x7a9/0x820 ... [ 0.619220] SMP alternatives: Something went horribly wrong trying to rewrite the CFI implementation.
*hang*
Signature · 1 line
Kees Cook
Quoted 19 lines · Kees Cook
Quoted 8 lines · Kees Cook
Quoted 6 lines · Peter Zijlstra
Quoted 2 lines · Kees Cook
-
CONFIG_CFI_CLANG=yfor x86 and arm64. (And disable FINEIBT since it isn't as secure as straight KCFI.)Oi ?
Quoted 7 lines
Same objection I always had[1]: moving the check into the destination means attacks with control over executable memory contents can just omit the check.
But now that I went to go look I see
0c3e806ec0f9("x86/cfi: Add boot time hash randomization") is only enabled under FINEIBT... seems better if that were always enabled...And FINEIBT actually can't be disabled... :|
Quoted 7 lines
And as it turns out
CFI_CLANGdoesn't work at all on v6.9...[ 0.587220] no CFI hash found at: __call_sites+0x339a8/0x34450 ffffffffac20cef8 00 00 00 00 00 [ 0.588226] WARNING: CPU: 0 PID: 0 at arch/x86/kernel/alternative.c:1182 __apply_fineibt+0x7a9/0x820 ... [ 0.619220] SMP alternatives: Something went horribly wrong trying to rewrite the CFI implementation.*hang*
Welcome to my TED talk.
I'll keep debugging this: boots fine on v6.8, but booting v6.9 with defconfig+CFI_CLANG _does_ work, so something in my .config broke it...
Signature · 1 line
Kees Cook
Quoted 11 lines · Kees Cook
Quoted 6 lines · Peter Zijlstra
Quoted 2 lines · Kees Cook
-
CONFIG_CFI_CLANG=yfor x86 and arm64. (And disable FINEIBT since it isn't as secure as straight KCFI.)Oi ?
Same objection I always had[1]: moving the check into the destination means attacks with control over executable memory contents can just omit the check.
I thought it was game over if you could write arbitrary test anyway?
The whole CFI thing was about clobbering data (function pointers to be more specific), and both are robust against that.
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Quoted 7 lines · Peter Zijlstra
Quoted 6 lines · Kees Cook
Quoted 5 lines · Peter Zijlstra
Quoted 2 lines · Kees Cook
-
CONFIG_CFI_CLANG=yfor x86 and arm64. (And disable FINEIBT since it isn't as secure as straight KCFI.)
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
Oi ?
Same objection I always had[1]: moving the check into the destination means attacks with control over executable memory contents can just omit the check.
I thought it was game over if you could write arbitrary test anyway?
Yes, an attack having arbitrary write control over an executable memory area is the place where CFI does get much weaker. But presently, there's no reason to make it easier. With the hash randomization we have, an attack needs to locate and read the kcfi_seed, otherwise everything else is a fixed value.
In the future, when we have viable X^R kernel text, then the trade-off becomes much more clear: we want FineIBT very very much. :)
Quoted 2 lines
The whole CFI thing was about clobbering data (function pointers to be more specific), and both are robust against that.
Yes, if the threat model is limited to arbitrary writes to function pointers, we're totally good with FineIBT.
-Kees
Signature · 1 line
Kees Cook