From: Mike Rapoport <rppt@kernel.org>
To: Peter Zijlstra <peterz@infradead.org>
Cc: "Borislav Petkov" <bp@alien8.de>,
"Dave Hansen" <dave.hansen@linux.intel.com>,
"Ingo Molnar" <mingo@redhat.com>, "J�rgen Gro�" <jgross@suse.com>,
"Mike Rapoport" <rppt@kernel.org>,
"H. Peter Anvin" <hpa@zytor.com>,
"Thomas Gleixner" <tglx@linutronix.de>, "Xin Li" <xin@zytor.com>,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
x86@kernel.org
Subject: [PATCH 4/5] x86/its: explicitly manage permissions for ITS pages
Date: Tue, 3 Jun 2025 14:14:44 +0300 [thread overview]
Message-ID: <20250603111446.2609381-5-rppt@kernel.org> (raw)
In-Reply-To: <20250603111446.2609381-1-rppt@kernel.org>
From: "Peter Zijlstra (Intel)" <peterz@infradead.org>
execmem_alloc() sets permissions differently depending on the kernel
configuration, CPU support for PSE and whether a page is allocated
before or after mark_rodata_ro().
Add tracking for pages allocated for ITS when patching the core kernel
and make sure the permissions for ITS pages are explicitly managed for
both kernel and module allocations.
Fixes: 872df34d7c51 ("x86/its: Use dynamic thunks for indirect branches")
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Co-developed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
---
arch/x86/kernel/alternative.c | 84 ++++++++++++++++++++++++++---------
1 file changed, 63 insertions(+), 21 deletions(-)
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 372ef5dff631..8289e9e1f954 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -138,6 +138,25 @@ static struct module *its_mod;
#endif
static void *its_page;
static unsigned int its_offset;
+struct its_array its_pages;
+
+static void *__its_alloc(struct its_array *pages)
+{
+ void *page __free(execmem) = execmem_alloc(EXECMEM_MODULE_TEXT, PAGE_SIZE);
+
+ if (!page)
+ return NULL;
+
+ void *tmp = krealloc(pages->pages, (pages->num+1) * sizeof(void *),
+ GFP_KERNEL);
+ if (!tmp)
+ return NULL;
+
+ pages->pages = tmp;
+ pages->pages[pages->num++] = page;
+
+ return no_free_ptr(page);
+}
/* Initialize a thunk with the "jmp *reg; int3" instructions. */
static void *its_init_thunk(void *thunk, int reg)
@@ -173,6 +192,21 @@ static void *its_init_thunk(void *thunk, int reg)
return thunk + offset;
}
+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);
+ }
+}
+
+static void its_fini_core(void)
+{
+ if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX))
+ its_pages_protect(&its_pages);
+ kfree(its_pages.pages);
+}
+
#ifdef CONFIG_MODULES
void its_init_mod(struct module *mod)
{
@@ -195,10 +229,8 @@ void its_fini_mod(struct module *mod)
its_page = NULL;
mutex_unlock(&text_mutex);
- for (int i = 0; i < mod->arch.its_pages.num; i++) {
- void *page = mod->arch.its_pages.pages[i];
- execmem_restore_rox(page, PAGE_SIZE);
- }
+ if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
+ its_pages_protect(&mod->arch.its_pages);
}
void its_free_mod(struct module *mod)
@@ -212,32 +244,38 @@ void its_free_mod(struct module *mod)
}
kfree(mod->arch.its_pages.pages);
}
-#endif /* CONFIG_MODULES */
-static void *its_alloc(void)
+static void *its_alloc_mod(void)
{
- void *page __free(execmem) = execmem_alloc(EXECMEM_MODULE_TEXT, PAGE_SIZE);
+ void *page = __its_alloc(&its_mod->arch.its_pages);
- if (!page)
- return NULL;
+ if (page)
+ execmem_make_temp_rw(page, PAGE_SIZE);
-#ifdef CONFIG_MODULES
- if (its_mod) {
- struct its_array *pages = &its_mod->arch.its_pages;
- void *tmp = krealloc(pages->pages,
- (pages->num+1) * sizeof(void *),
- GFP_KERNEL);
- if (!tmp)
- return NULL;
+ return page;
+}
+#endif /* CONFIG_MODULES */
- pages->pages = tmp;
- pages->pages[pages->num++] = page;
+static void *its_alloc_core(void)
+{
+ void *page = __its_alloc(&its_pages);
+ if (page) {
execmem_make_temp_rw(page, PAGE_SIZE);
+ set_memory_x((unsigned long)page, 1);
}
+
+ return page;
+}
+
+static void *its_alloc(void)
+{
+#ifdef CONFIG_MODULES
+ if (its_mod)
+ return its_alloc_mod();
#endif /* CONFIG_MODULES */
- return no_free_ptr(page);
+ return its_alloc_core();
}
static void *its_allocate_thunk(int reg)
@@ -291,7 +329,9 @@ u8 *its_static_thunk(int reg)
return thunk;
}
-#endif
+#else
+static inline void its_fini_core(void) {}
+#endif /* CONFIG_MITIGATION_ITS */
/*
* Nomenclature for variable names to simplify and clarify this code and ease
@@ -2368,6 +2408,8 @@ void __init alternative_instructions(void)
apply_retpolines(__retpoline_sites, __retpoline_sites_end);
apply_returns(__return_sites, __return_sites_end);
+ its_fini_core();
+
/*
* Adjust all CALL instructions to point to func()-10, including
* those in .altinstr_replacement.
--
2.47.2
next prev parent reply other threads:[~2025-06-03 11:15 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-03 11:14 [PATCH 0/5] Fixes for ITS mitigation and execmem Mike Rapoport
2025-06-03 11:14 ` [PATCH 1/5] x86/mm/pat: don't collapse pages without PSE set Mike Rapoport
2025-06-03 11:14 ` [PATCH 2/5] x86/Kconfig: only enable ROX cache in execmem when STRICT_MODULE_RWX is set Mike Rapoport
2025-06-11 9:30 ` [tip: x86/urgent] " tip-bot2 for Mike Rapoport (Microsoft)
2025-06-03 11:14 ` [PATCH 3/5] x86/its: move its_pages array to struct mod_arch_specific Mike Rapoport
2025-06-03 11:18 ` kernel test robot
2025-06-11 9:30 ` [tip: x86/urgent] " tip-bot2 for Mike Rapoport (Microsoft)
2025-06-03 11:14 ` Mike Rapoport [this message]
2025-06-03 13:58 ` [PATCH 4/5] x86/its: explicitly manage permissions for ITS pages Peter Zijlstra
2025-06-03 14:36 ` Mike Rapoport
2025-06-03 14:45 ` Peter Zijlstra
2025-06-11 21:09 ` Chuck Zmudzinski
2025-06-05 9:23 ` Nikolay Borisov
2025-06-11 9:30 ` [tip: x86/urgent] " tip-bot2 for Peter Zijlstra (Intel)
2025-06-03 11:14 ` [PATCH 5/5] Revert "mm/execmem: Unify early execmem_cache behaviour" Mike Rapoport
2025-06-11 9:30 ` [tip: x86/urgent] " tip-bot2 for Mike Rapoport (Microsoft)
2025-06-10 6:00 ` [PATCH 0/5] Fixes for ITS mitigation and execmem Jürgen Groß
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250603111446.2609381-5-rppt@kernel.org \
--to=rppt@kernel.org \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=jgross@suse.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=stable@vger.kernel.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
--cc=xin@zytor.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.