summaryrefslogtreecommitdiff
path: root/mm/execmem.c
diff options
context:
space:
mode:
authorMike Rapoport (Microsoft) <rppt@kernel.org>2025-01-26 09:47:29 +0200
committerPeter Zijlstra <peterz@infradead.org>2025-02-03 11:46:02 +0100
commit05e555b817262b5df6aa3a73df8b3dc9d388a3b4 (patch)
treed5b3dd4fa9ce56645cd2180edefa5607d6e59202 /mm/execmem.c
parent925f426451182a9f3e0f7f0e7e928f32f81a966a (diff)
execmem: add API for temporal remapping as RW and restoring ROX afterwards
Using a writable copy for ROX memory is cumbersome and error prone. Add API that allow temporarily remapping of ranges in the ROX cache as writable and then restoring their read-only-execute permissions. This API will be later used in modules code and will allow removing nasty games with writable copy in alternatives patching on x86. The restoring of the ROX permissions relies on the ability of architecture to reconstruct large pages in its set_memory_rox() method. Signed-off-by: "Mike Rapoport (Microsoft)" <rppt@kernel.org> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20250126074733.1384926-6-rppt@kernel.org
Diffstat (limited to 'mm/execmem.c')
-rw-r--r--mm/execmem.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/mm/execmem.c b/mm/execmem.c
index 04b0bf1b5025..e6c4f5076ca8 100644
--- a/mm/execmem.c
+++ b/mm/execmem.c
@@ -335,6 +335,28 @@ static bool execmem_cache_free(void *ptr)
return true;
}
+
+int execmem_make_temp_rw(void *ptr, size_t size)
+{
+ unsigned int nr = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ unsigned long addr = (unsigned long)ptr;
+ int ret;
+
+ ret = set_memory_nx(addr, nr);
+ if (ret)
+ return ret;
+
+ return set_memory_rw(addr, nr);
+}
+
+int execmem_restore_rox(void *ptr, size_t size)
+{
+ unsigned int nr = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ unsigned long addr = (unsigned long)ptr;
+
+ return set_memory_rox(addr, nr);
+}
+
#else /* CONFIG_ARCH_HAS_EXECMEM_ROX */
static void *execmem_cache_alloc(struct execmem_range *range, size_t size)
{