* [PATCH] x86/its: Make ITS thunk pages read-only without the ROX execmem cache
@ 2026-10-01 13:22 Frédéric MARIE-JOSEPH
2026-10-01 15:24 ` Dave Hansen
0 siblings, 1 reply; 3+ messages in thread
From: Frédéric MARIE-JOSEPH @ 2026-10-01 13:22 UTC (permalink / raw)
To: x86, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen
Cc: H. Peter Anvin, Peter Zijlstra, Mike Rapoport, linux-kernel
[-- Attachment #1.1: Type: text/plain, Size: 1743 bytes --]
Hello to list,
That's my first post so I hope I do things right. I found what seems to me
like a bug, and worked with Claude to find a patch. Hope it will be usefull.
With CONFIG_MODULES=n there is no STRICT_MODULE_RWX, so x86 does not
select ARCH_HAS_EXECMEM_ROX and execmem_restore_rox() is the stub that
returns 0. its_pages_protect() relies on it alone, so the dynamic ITS
thunk pages, made executable by set_memory_x() in its_alloc(), stay
writable and executable for the life of the kernel. CONFIG_DEBUG_WX
reports them on every boot:
x86/mm: Checked W+X mappings: FAILED, 7 W+X pages found.
The attached patch makes the pages read-only with set_memory_ro() when
the ROX cache is not built; when it is, nothing changes.
Tested on a CONFIG_MODULES=n x86_64 build of 6.18.53 booted under
QEMU/KVM: with the change, the boots report "x86/mm: Checked W+X
mappings: passed, no W+X pages found." and no warning. On mainline
(551c722f4), whose its_pages_protect() is identical,
arch/x86/kernel/alternative.o builds without warnings with that
configuration and with x86_64_defconfig; mainline itself was not booted.
The bug was found, and the fix and its message written, with the help
of an AI coding assistant (Claude, Anthropic), and reviewed by me.
The patch is attached in git format-patch form (my mail client would
damage it inline); it applies with "git am". I can resend it inline
with git send-email if you prefer.
Fixes: a82b26451de1 ("x86/its: explicitly manage permissions for ITS pages")
Regards,
Frederic MARIE-JOSEPH
Frédéric MARIE-JOSEPH
*N° TVA intracommunautaire FR78788461903*
*N° SIRET 78846190300015/78846190300023*
*fmjconsulting.fr <http://fmjconsulting.fr>*
[-- Attachment #1.2: Type: text/html, Size: 2964 bytes --]
[-- Attachment #2: 0001-x86-its-Make-ITS-thunk-pages-read-only-without-the-R.patch --]
[-- Type: text/x-patch, Size: 2471 bytes --]
From ca4f1442f2f29de770fd23b66ac3ccc3f9295722 Mon Sep 17 00:00:00 2001
From: Frederic MARIE-JOSEPH <fredericmariejoseph@gmail.com>
Date: Thu, 1 Oct 2026 15:00:00 +0200
Subject: [PATCH] x86/its: Make ITS thunk pages read-only without the ROX
execmem cache
With CONFIG_MODULES=n there is no STRICT_MODULE_RWX, so x86 does not
select ARCH_HAS_EXECMEM_ROX and execmem_restore_rox() is the stub that
returns 0. its_pages_protect() relies on it alone, so the dynamic ITS
thunk pages, made executable by set_memory_x() in its_alloc(), stay
writable and executable for the life of the kernel. CONFIG_DEBUG_WX
reports them on every boot:
x86/mm: Checked W+X mappings: FAILED, 7 W+X pages found.
Make the pages read-only with set_memory_ro() when the ROX cache is not
built. When it is, nothing changes.
Found by the W+X check of a CONFIG_MODULES=n x86_64 build of 6.18.53
booted under QEMU/KVM. Tested on that build only: with the change, both
boots of the test report "x86/mm: Checked W+X mappings: passed, no W+X
pages found." and no warning. On mainline, whose its_pages_protect() is
identical, arch/x86/kernel/alternative.o builds without warnings with that
CONFIG_MODULES=n configuration and with x86_64_defconfig (modules and the
ROX cache on, where the IS_ENABLED() branch keeps the current call);
mainline itself was not booted.
The bug was found, and the fix and this message written, with the help
of an AI coding assistant (Claude, Anthropic), and reviewed by me.
Fixes: a82b26451de1 ("x86/its: explicitly manage permissions for ITS pages")
Assisted-by: LLM
Signed-off-by: Frederic MARIE-JOSEPH <fredericmariejoseph@gmail.com>
---
arch/x86/kernel/alternative.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 582c6d830..ad08ac9b1 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -168,7 +168,15 @@ static void its_pages_protect(struct its_array *pages)
{
for (int i = 0; i < pages->num; i++) {
void *page = pages->pages[i];
- execmem_restore_rox(page, PAGE_SIZE);
+ /*
+ * Without the ROX execmem cache (no STRICT_MODULE_RWX, so no
+ * modules) execmem_restore_rox() is a stub and the thunk pages
+ * would stay writable and executable: make them read-only.
+ */
+ if (IS_ENABLED(CONFIG_ARCH_HAS_EXECMEM_ROX))
+ execmem_restore_rox(page, PAGE_SIZE);
+ else
+ set_memory_ro((unsigned long)page, 1);
}
}
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] x86/its: Make ITS thunk pages read-only without the ROX execmem cache
2026-10-01 13:22 [PATCH] x86/its: Make ITS thunk pages read-only without the ROX execmem cache Frédéric MARIE-JOSEPH
@ 2026-10-01 15:24 ` Dave Hansen
2026-10-01 16:38 ` Frédéric MARIE-JOSEPH
0 siblings, 1 reply; 3+ messages in thread
From: Dave Hansen @ 2026-10-01 15:24 UTC (permalink / raw)
To: Frédéric MARIE-JOSEPH, x86, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen
Cc: H. Peter Anvin, Peter Zijlstra, Mike Rapoport, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1448 bytes --]
On 10/1/26 06:22, Frédéric MARIE-JOSEPH wrote:
> That's my first post so I hope I do things right. I found what seems to
> me like a bug, and worked with Claude to find a patch. Hope it will be
> usefull.
Your mailer is sending out HTML, but there was a plain-text version too,
so the message at least made it to the archives. Using git-send-email is
the most foolproof way to send these things, fwiw.
> With CONFIG_MODULES=n there is no STRICT_MODULE_RWX, so x86 does not
> select ARCH_HAS_EXECMEM_ROX and execmem_restore_rox() is the stub that
> returns 0.
Ugh. The origin of this seems to be:
select ARCH_HAS_EXECMEM_ROX if X86_64 &&
STRICT_MODULE_RWX
from:
> commit 47410d839fcda6890cb82828f874f97710982f24
> Author: Mike Rapoport (Microsoft) <rppt@kernel.org>
> Date: Tue Jun 3 14:14:42 2025 +0300
>
> x86/Kconfig: only enable ROX cache in execmem when STRICT_MODULE_RWX is set
That commit is trying to change execmem internal details via an
arch-specific Kconfig tweak. It's also logically a bit silly that what
an arch supports:
ARCH_HAS_EXECMEM_ROX
depends on a module-specific option:
STRICT_MODULE_RWX
If execmem is being too aggressive on for modules on !STRICT_MODULE_RWX
configs, shouldn't the fix be in execmem *module* code?
Maybe something along the line of the lightly-tested attached patch? I
see the "11 W+X pages found" message without it, and the message goes
away when it is applied.
[-- Attachment #2: x86-STRICT_MODULE_RWX.patch --]
[-- Type: text/x-patch, Size: 1232 bytes --]
---
b/arch/x86/Kconfig | 2 +-
b/kernel/module/main.c | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff -puN arch/x86/Kconfig~x86-STRICT_MODULE_RWX arch/x86/Kconfig
--- a/arch/x86/Kconfig~x86-STRICT_MODULE_RWX 2026-10-01 06:31:14.379577124 -0700
+++ b/arch/x86/Kconfig 2026-10-01 06:31:39.777436090 -0700
@@ -85,7 +85,7 @@ config X86
select ARCH_HAS_DMA_OPS if GART_IOMMU || XEN
select ARCH_HAS_EARLY_DEBUG if KGDB
select ARCH_HAS_ELF_RANDOMIZE
- select ARCH_HAS_EXECMEM_ROX if X86_64 && STRICT_MODULE_RWX
+ select ARCH_HAS_EXECMEM_ROX if X86_64
select ARCH_HAS_FAST_MULTIPLIER
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_GCOV_PROFILE_ALL
diff -puN kernel/module/main.c~x86-STRICT_MODULE_RWX kernel/module/main.c
--- a/kernel/module/main.c~x86-STRICT_MODULE_RWX 2026-10-01 06:44:42.417795788 -0700
+++ b/kernel/module/main.c 2026-10-01 06:51:28.048722976 -0700
@@ -1355,7 +1355,8 @@ static int module_memory_alloc(struct mo
if (!ptr)
return -ENOMEM;
- mod->mem[type].is_rox = execmem_is_rox(execmem_type);
+ if (IS_ENABLED(STRICT_MODULE_RWX))
+ mod->mem[type].is_rox = execmem_is_rox(execmem_type);
/*
* The pointer to these blocks of memory are stored on the module
_
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] x86/its: Make ITS thunk pages read-only without the ROX execmem cache
2026-10-01 15:24 ` Dave Hansen
@ 2026-10-01 16:38 ` Frédéric MARIE-JOSEPH
0 siblings, 0 replies; 3+ messages in thread
From: Frédéric MARIE-JOSEPH @ 2026-10-01 16:38 UTC (permalink / raw)
To: Dave Hansen
Cc: x86, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
H. Peter Anvin, Peter Zijlstra, Mike Rapoport, linux-kernel
On 10/1/26 08:24, Dave Hansen wrote:
> Your mailer is sending out HTML, but there was a plain-text version too,
> so the message at least made it to the archives. Using git-send-email is
> the most foolproof way to send these things, fwiw.
Thanks, noted. I'll try to use git send-email next time.
> If execmem is being too aggressive on for modules on !STRICT_MODULE_RWX
> configs, shouldn't the fix be in execmem *module* code?
Ok I see. Better to fix it at the root cause rather than in its_pages_protect().
One thing in the attached patch, which Claude noticed and I didn't,
probably a typo:
> + if (IS_ENABLED(STRICT_MODULE_RWX))
IS_ENABLED() takes the full symbol name, so this should be
IS_ENABLED(CONFIG_STRICT_MODULE_RWX). As written it is always 0.
In my config (CONFIG_MODULES=n, 6.18.53, ITS mitigation active under
KVM) only the Kconfig hunk is built. I tested your patch instead of
mine. Every boot reports
"x86/mm: Checked W+X mappings: passed, no W+X pages found." (it reported
7 W+X pages before), and our boot tests (kselftests, LKDTM,
kernel-hardening-checker) still pass. Thank you for your quick review.
Tested-by: Frederic MARIE-JOSEPH <fredericmariejoseph@gmail.com>
Regards,
Frederic
Frédéric MARIE-JOSEPH
N° TVA intracommunautaire FR78788461903
N° SIRET 78846190300015/78846190300023
fmjconsulting.fr
Le jeu. 1 oct. 2026 à 17:24, Dave Hansen <dave.hansen@intel.com> a écrit :
>
> On 10/1/26 06:22, Frédéric MARIE-JOSEPH wrote:
> > That's my first post so I hope I do things right. I found what seems to
> > me like a bug, and worked with Claude to find a patch. Hope it will be
> > usefull.
>
> Your mailer is sending out HTML, but there was a plain-text version too,
> so the message at least made it to the archives. Using git-send-email is
> the most foolproof way to send these things, fwiw.
>
> > With CONFIG_MODULES=n there is no STRICT_MODULE_RWX, so x86 does not
> > select ARCH_HAS_EXECMEM_ROX and execmem_restore_rox() is the stub that
> > returns 0.
>
> Ugh. The origin of this seems to be:
>
> select ARCH_HAS_EXECMEM_ROX if X86_64 &&
> STRICT_MODULE_RWX
> from:
>
> > commit 47410d839fcda6890cb82828f874f97710982f24
> > Author: Mike Rapoport (Microsoft) <rppt@kernel.org>
> > Date: Tue Jun 3 14:14:42 2025 +0300
> >
> > x86/Kconfig: only enable ROX cache in execmem when STRICT_MODULE_RWX is set
>
> That commit is trying to change execmem internal details via an
> arch-specific Kconfig tweak. It's also logically a bit silly that what
> an arch supports:
>
> ARCH_HAS_EXECMEM_ROX
>
> depends on a module-specific option:
>
> STRICT_MODULE_RWX
>
> If execmem is being too aggressive on for modules on !STRICT_MODULE_RWX
> configs, shouldn't the fix be in execmem *module* code?
>
> Maybe something along the line of the lightly-tested attached patch? I
> see the "11 W+X pages found" message without it, and the message goes
> away when it is applied.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-01 16:38 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-01 13:22 [PATCH] x86/its: Make ITS thunk pages read-only without the ROX execmem cache Frédéric MARIE-JOSEPH
2026-10-01 15:24 ` Dave Hansen
2026-10-01 16:38 ` Frédéric MARIE-JOSEPH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®