mm/kfence/core.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
KFENCE does not currently support KASAN hardware tags. As a result, the
two features are incompatible when enabled simultaneously.
Given that MTE provides deterministic protection and KFENCE is a
sampling-based debugging tool, prioritize the stronger hardware
protections. Disable KFENCE initialization and free the pre-allocated
pool if KASAN hardware tags are detected to ensure the system maintains
the security guarantees provided by MTE.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Ernesto Martinez Garcia <ernesto.martinezgarcia@tugraz.at>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Kees Cook <kees@kernel.org>
Cc: <stable@vger.kernel.org>
Fixes: 0ce20dd84089 ("mm: add Kernel Electric-Fence infrastructure")
Suggested-by: Marco Elver <elver@google.com>
Signed-off-by: Alexander Potapenko <glider@google.com>
---
mm/kfence/core.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/mm/kfence/core.c b/mm/kfence/core.c
index 4f79ec7207525..71f87072baf9b 100644
--- a/mm/kfence/core.c
+++ b/mm/kfence/core.c
@@ -13,6 +13,7 @@
#include <linux/hash.h>
#include <linux/irq_work.h>
#include <linux/jhash.h>
+#include <linux/kasan-enabled.h>
#include <linux/kcsan-checks.h>
#include <linux/kfence.h>
#include <linux/kmemleak.h>
@@ -911,6 +912,20 @@ void __init kfence_alloc_pool_and_metadata(void)
if (!kfence_sample_interval)
return;
+ /*
+ * If KASAN hardware tags are enabled, disable KFENCE, because it
+ * does not support MTE yet.
+ */
+ if (kasan_hw_tags_enabled()) {
+ pr_info("disabled as KASAN HW tags are enabled\n");
+ if (__kfence_pool) {
+ memblock_free(__kfence_pool, KFENCE_POOL_SIZE);
+ __kfence_pool = NULL;
+ }
+ kfence_sample_interval = 0;
+ return;
+ }
+
/*
* If the pool has already been initialized by arch, there is no need to
* re-allocate the memory pool.
--
2.53.0.273.g2a3d683680-goog
On Fri, 13 Feb 2026 at 10:54, Alexander Potapenko <glider@google.com> wrote:
>
> KFENCE does not currently support KASAN hardware tags. As a result, the
> two features are incompatible when enabled simultaneously.
>
> Given that MTE provides deterministic protection and KFENCE is a
> sampling-based debugging tool, prioritize the stronger hardware
> protections. Disable KFENCE initialization and free the pre-allocated
> pool if KASAN hardware tags are detected to ensure the system maintains
> the security guarantees provided by MTE.
>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Andrey Konovalov <andreyknvl@gmail.com>
> Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
> Cc: Dmitry Vyukov <dvyukov@google.com>
> Cc: Ernesto Martinez Garcia <ernesto.martinezgarcia@tugraz.at>
> Cc: Greg KH <gregkh@linuxfoundation.org>
> Cc: Kees Cook <kees@kernel.org>
> Cc: <stable@vger.kernel.org>
> Fixes: 0ce20dd84089 ("mm: add Kernel Electric-Fence infrastructure")
> Suggested-by: Marco Elver <elver@google.com>
> Signed-off-by: Alexander Potapenko <glider@google.com>
Reviewed-by: Marco Elver <elver@google.com>
Just double-checking this is explicitly ok: If this is being skipped
enablement at boot, a user is still free to do 'echo 123 >
/sys/module/kfence/parameters/sample_interval' to re-enable KFENCE? In
my opinion, this should be allowed.
Thanks!
> ---
> mm/kfence/core.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/mm/kfence/core.c b/mm/kfence/core.c
> index 4f79ec7207525..71f87072baf9b 100644
> --- a/mm/kfence/core.c
> +++ b/mm/kfence/core.c
> @@ -13,6 +13,7 @@
> #include <linux/hash.h>
> #include <linux/irq_work.h>
> #include <linux/jhash.h>
> +#include <linux/kasan-enabled.h>
> #include <linux/kcsan-checks.h>
> #include <linux/kfence.h>
> #include <linux/kmemleak.h>
> @@ -911,6 +912,20 @@ void __init kfence_alloc_pool_and_metadata(void)
> if (!kfence_sample_interval)
> return;
>
> + /*
> + * If KASAN hardware tags are enabled, disable KFENCE, because it
> + * does not support MTE yet.
> + */
> + if (kasan_hw_tags_enabled()) {
> + pr_info("disabled as KASAN HW tags are enabled\n");
> + if (__kfence_pool) {
> + memblock_free(__kfence_pool, KFENCE_POOL_SIZE);
> + __kfence_pool = NULL;
> + }
> + kfence_sample_interval = 0;
> + return;
> + }
> +
> /*
> * If the pool has already been initialized by arch, there is no need to
> * re-allocate the memory pool.
> --
> 2.53.0.273.g2a3d683680-goog
>
On Fri Feb 13, 2026 at 11:50 AM CET, Marco Elver wrote: > On Fri, 13 Feb 2026 at 10:54, Alexander Potapenko <glider@google.com> wrote: >> >> KFENCE does not currently support KASAN hardware tags. As a result, the >> two features are incompatible when enabled simultaneously. >> >> Given that MTE provides deterministic protection and KFENCE is a >> sampling-based debugging tool, prioritize the stronger hardware >> protections. Disable KFENCE initialization and free the pre-allocated >> pool if KASAN hardware tags are detected to ensure the system maintains >> the security guarantees provided by MTE. > > Just double-checking this is explicitly ok: If this is being skipped > enablement at boot, a user is still free to do 'echo 123 > > /sys/module/kfence/parameters/sample_interval' to re-enable KFENCE? In > my opinion, this should be allowed. Should work, as the late enable codepath is: - param_set_sample_interval() - kfence_enable_late() - kfence_init_late() While the check is only present at: - mm_core_init() - kfence_alloc_pool_and_metadata() - kasan_hw_tags_enabled() However the late activation triggers BUG_ON or KASAN invalid access issues at the moment: ~ # dmesg | grep 'disabled as' [ 0.000000] kfence: disabled as KASAN HW tags are enabled ~ # echo 100 > /sys/module/kfence/parameters/sample_interval [ 30.440993] ================================================================== [ 30.442418] BUG: KASAN: invalid-access in __memset+0x10/0x20 [ 30.443275] Write at addr f4f00000c2e34000 by task sh/1 [ 30.443420] Pointer tag: [f4], memory tag: [f1] [ 30.443448] ... [ 30.445742] ================================================================== [ 30.445946] Disabling lock debugging due to kernel taint [ 30.459644] kfence: initialized - using 2097152 bytes for 255 objects at 0xf5f00000c1c00000-0xf5f00000c1e00000 Likely because the KFENCE pool/metadata memory is allocated and tagged by MTE: [ 7.590336] kfence: initialized - using 2097152 bytes for 255 objects at 0xf2f00000c1600000-0xf2f00000c1800000 ... [ 7.710112] kfence: initialized - using 2097152 bytes for 255 objects at 0xf1f00000c1600000-0xf1f00000c1800000 ... [ 6.627959] kfence: initialized - using 2097152 bytes for 255 objects at 0xf8f00000c1e00000-0xf8f00000c2000000 ... [ 19.137156] kfence: initialized - using 2097152 bytes for 255 objects at 0xf3f00000c1e00000-0xf3f00000c2000000 Which seems to be an upstream bug of KFENCE+MTE, as I can reproduce the same issue on mainline 6.19 without the patch applied: # uname -r 6.19.0 # cat /proc/cmdline root=/dev/vda console=ttyAMA0 rw rootwait earlycon debug hash_pointers=never kfence.sample_interval=0 # echo 100 > /sys/module/kfence/parameters/sample_interval [ 45.555499] ================================================================== [ 45.556989] BUG: KASAN: invalid-access in __memset+0x10/0x20 [ 45.557844] Write at addr f8f00000c3032000 by task sh/148 [ 45.558063] Pointer tag: [f8], memory tag: [f4] ... [ 45.560695] Disabling lock debugging dHey thank you will take a looksie and tell youe to kernel taint [ 45.574599] kfence: initialized - using 2097152 bytes for 255 objects at 0xf4f00000c1600000-0xf4f00000c1800000 Disabling and enabling won't trigger as the KFENCE pool is not freed on disable. To trigger the bug it is required to go through the kfence_init_late() path: KFENCE disabled at boot time. Note: Tested with qemu-system-aarch64 -cpu max -machine virt,mte=on (10.1.3) Changing kfence_init_late() pool and metadata allocations to use the __GFP_SKIP_KASAN flag fixes it: ~ # echo 100 > /sys/module/kfence/parameters/sample_interval [ 19.488734] kfence: initialized - using 2097152 bytes for 255 objects at 0xfff00000c1600000-0xfff00000c1800000 ~ # cat /sys/kernel/debug/kfence/stats enabled: 1 currently allocated: 1 total allocations: 12 total frees: 11 ... ~ # echo 0 > /sys/module/kfence/parameters/sample_interval [ 778.414494] kfence: disabled ~ # echo 100 > /sys/module/kfence/parameters/sample_interval [ 784.215866] kfence: re-enabled ~ # cat /sys/kernel/debug/kfence/stats enabled: 1 currently allocated: 2 total allocations: 32 total frees: 30 ... But this requires adding __GFP_SKIP_KASAN as allowed in __alloc_contig_verify_gfp_mask I think. Unsure if there is a cleaner way of doing it, or if changing __alloc_contig_verify_gfp_mask could break something else unexpectedly. I would be happy to try to submit a patch for it :)
> But this requires adding __GFP_SKIP_KASAN as allowed in > __alloc_contig_verify_gfp_mask I think. Unsure if there is a cleaner way > of doing it, or if changing __alloc_contig_verify_gfp_mask could break > something else unexpectedly. > > I would be happy to try to submit a patch for it :) Sorry, I was working on a patch when I saw this email. Let me send it.
© 2016 - 2026 Red Hat, Inc.