I fell onto a bunch of WX mappings in the linear mapping after a module
gets unloaded, this is because our module_alloc() does not set the
VM_FLUSH_RESET_PERMS flag (patch 1) and that
set_direct_map_default_noflush() must clean the X bit (patch 2).
Note that the Fixes tags are correct but patch 2 will fail to apply
since a change in this function just landed in 6.7.
Alexandre Ghiti (2):
riscv: Fix module_alloc() that did not reset the linear mapping
permissions
riscv: Fix set_direct_map_default_noflush() to reset _PAGE_EXEC
arch/riscv/kernel/module.c | 3 ++-
arch/riscv/mm/pageattr.c | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
--
2.39.2
After unloading a module, we must reset the linear mapping permissions,
see the example below:
Before unloading a module:
0xffffaf809d65d000-0xffffaf809d6dc000 0x000000011d65d000 508K PTE . .. .. D A G . . W R V
0xffffaf809d6dc000-0xffffaf809d6dd000 0x000000011d6dc000 4K PTE . .. .. D A G . . . R V
0xffffaf809d6dd000-0xffffaf809d6e1000 0x000000011d6dd000 16K PTE . .. .. D A G . . W R V
0xffffaf809d6e1000-0xffffaf809d6e7000 0x000000011d6e1000 24K PTE . .. .. D A G . X . R V
After unloading a module:
0xffffaf809d65d000-0xffffaf809d6e1000 0x000000011d65d000 528K PTE . .. .. D A G . . W R V
0xffffaf809d6e1000-0xffffaf809d6e7000 0x000000011d6e1000 24K PTE . .. .. D A G . X W R V
The last mapping is not reset and we end up with WX mappings in the linear
mapping.
So add VM_FLUSH_RESET_PERMS to our module_alloc() definition.
Fixes: 0cff8bff7af8 ("riscv: avoid the PIC offset of static percpu data in module beyond 2G limits")
Signed-off-by: Alexandre Ghiti <[email protected]>
---
arch/riscv/kernel/module.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
index aac019ed63b1..862834bb1d64 100644
--- a/arch/riscv/kernel/module.c
+++ b/arch/riscv/kernel/module.c
@@ -894,7 +894,8 @@ void *module_alloc(unsigned long size)
{
return __vmalloc_node_range(size, 1, MODULES_VADDR,
MODULES_END, GFP_KERNEL,
- PAGE_KERNEL, 0, NUMA_NO_NODE,
+ PAGE_KERNEL, VM_FLUSH_RESET_PERMS,
+ NUMA_NO_NODE,
__builtin_return_address(0));
}
#endif
--
2.39.2
When resetting the linear mapping permissions, we must make sure that we
clear the X bit so that do not end up with WX mappings (since we set
PAGE_KERNEL).
Fixes: 395a21ff859c ("riscv: add ARCH_HAS_SET_DIRECT_MAP support")
Signed-off-by: Alexandre Ghiti <[email protected]>
---
arch/riscv/mm/pageattr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
index 96cbda683936..01398fee5cf8 100644
--- a/arch/riscv/mm/pageattr.c
+++ b/arch/riscv/mm/pageattr.c
@@ -383,7 +383,7 @@ int set_direct_map_invalid_noflush(struct page *page)
int set_direct_map_default_noflush(struct page *page)
{
return __set_memory((unsigned long)page_address(page), 1,
- PAGE_KERNEL, __pgprot(0));
+ PAGE_KERNEL, __pgprot(_PAGE_EXEC));
}
#ifdef CONFIG_DEBUG_PAGEALLOC
--
2.39.2
Hello:
This series was applied to riscv/linux.git (fixes)
by Palmer Dabbelt <[email protected]>:
On Wed, 13 Dec 2023 14:40:25 +0100 you wrote:
> I fell onto a bunch of WX mappings in the linear mapping after a module
> gets unloaded, this is because our module_alloc() does not set the
> VM_FLUSH_RESET_PERMS flag (patch 1) and that
> set_direct_map_default_noflush() must clean the X bit (patch 2).
>
> Note that the Fixes tags are correct but patch 2 will fail to apply
> since a change in this function just landed in 6.7.
>
> [...]
Here is the summary with links:
- [-fixes,1/2] riscv: Fix module_alloc() that did not reset the linear mapping permissions
https://git.kernel.org/riscv/c/2f748fa7b60a
- [-fixes,2/2] riscv: Fix set_direct_map_default_noflush() to reset _PAGE_EXEC
https://git.kernel.org/riscv/c/3b5c14361d61
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html