diff options
author | Mike Rapoport (Microsoft) <rppt@kernel.org> | 2025-01-26 09:47:29 +0200 |
---|---|---|
committer | Peter Zijlstra <peterz@infradead.org> | 2025-02-03 11:46:02 +0100 |
commit | 05e555b817262b5df6aa3a73df8b3dc9d388a3b4 (patch) | |
tree | d5b3dd4fa9ce56645cd2180edefa5607d6e59202 /mm/execmem.c | |
parent | 925f426451182a9f3e0f7f0e7e928f32f81a966a (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.c | 22 |
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) { |