diff --git a/drivers/misc/lkdtm_perms.c b/drivers/misc/lkdtm_perms.c index 45f1c0f966123c7b3870e4f42d724270f4f75e5f..c7635a79341fb3e52d527135db2a1c958cc7e087 100644 --- a/drivers/misc/lkdtm_perms.c +++ b/drivers/misc/lkdtm_perms.c @@ -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(); } diff --git a/mm/memory.c b/mm/memory.c index e18c57bdc75c4c96e3ef79546afe11fab5a3c07a..485f12d8ad5c84abdf93fae26e4c92d175b4a13e 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -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. diff --git a/mm/nommu.c b/mm/nommu.c index 8b8faaf2a9e95cfc607ff1a5a37c83eadfda59fe..9720e0bab0298fcec3855d7300934eb9e6223b4c 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1878,6 +1878,7 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in mmput(mm); return len; } +EXPORT_SYMBOL_GPL(access_process_vm); /** * nommu_shrink_inode_mappings - Shrink the shared mappings on an inode