lkdtm: Do not use flush_icache_range() on user addresses
Subsystems (4)
PATCH 1/1 lkdtm: Do not use flush_icache_range() on user addresses
From: Catalin Marinas <[email protected]>
The flush_icache_range() API is meant to be used on kernel addresses only as it may not have the infrastructure (exception entries) to handle user memory faults.
The lkdtm execute_user_location() function tests the kernel execution of user space addresses by mmap'ing an anonymous page, copying some code together with cache maintenance and attempting to run it. However, the cache maintenance step may fail because of the incorrect API usage described above. The patch changes lkdtm to use access_process_vm() for copying the code into user space which would take care of the necessary cache maintenance.
---
Since this now adds an export, we should probably delay this to v4.10. (And I've fixed my build tests to actually do CONFIG_LKDTM=m instead of lying to me.)
--- drivers/misc/lkdtm_perms.c | 7 +++++-- mm/memory.c | 1 + mm/nommu.c | 1 + 3 files changed, 7 insertions(+), 2 deletions(-)
drivers/misc/lkdtm_perms.c +5 -2
@@ -60,15 +60,18 @@ static noinline void execute_location(void *dst, bool write)static void execute_user_location (void *dst) { +int copied; +/* Intentionally crossing kernel/user memory boundary. */ void (*func)(void ) = dst;pr_info ("attempting ok execution at %p\n" , do_nothing);do_nothing (); -if (copy_to_user ((void __user *)dst, do_nothing,EXEC_SIZE )) + copied =access_process_vm (current, (unsigned long )dst, do_nothing, +EXEC_SIZE ,FOLL_WRITE ); +if (copied <EXEC_SIZE )return ; -flush_icache_range ((unsigned long )dst, (unsigned long )dst +EXEC_SIZE );pr_info ("attempting bad execution at %p\n" , func);func (); }
mm/memory.c +1 -0
@@ -3966,6 +3966,7 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr,return ret; } +EXPORT_SYMBOL_GPL (access_process_vm);/* * Print the name of a VMA.
mm/nommu.c +1 -0
@@ -1878,6 +1878,7 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, inmmput (mm);return len; } +EXPORT_SYMBOL_GPL (access_process_vm);/** * nommu_shrink_inode_mappings - Shrink the shared mappings on an inode
Signature · 12 lines
2.7.4 -- Kees Cook Nexus Security -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>