ARM64: Fix for changing write protected kernel memory 86/177386/1
authorVyacheslav Cherkashin <v.cherkashin@samsung.com>
Fri, 13 Apr 2018 15:04:09 +0000 (18:04 +0300)
committerVyacheslav Cherkashin <v.cherkashin@samsung.com>
Fri, 27 Apr 2018 11:56:53 +0000 (14:56 +0300)
Use the private kernel function arch64_insn_patch_text()
for changing kernel memory.

Change-Id: Id9eec388f135ec15f82b46d2c4227a48ae8b6e80
Signed-off-by: Vyacheslav Cherkashin <v.cherkashin@samsung.com>
modules/kprobe/arch/arm64/swap-asm/swap_kprobes.c

index 77970efec5c4e6d9523b4a825abceb3a0a61077f..150809173114915923a935ce54700ba328e85bc5 100644 (file)
@@ -27,6 +27,9 @@
  */
 
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+
 #include <linux/kconfig.h>
 
 #ifdef CONFIG_SWAP_KERNEL_IMMUTABLE
@@ -72,10 +75,14 @@ static void flush_icache(unsigned long addr, size_t size)
        flush_icache_range(addr, addr + size);
 }
 
+static int (*fn_aarch64_insn_patch_text)(void *addrs[], u32 insns[], int cnt);
+
 static void write_u32(u32 *addr, u32 val)
 {
-       *addr = val;
-       flush_icache((unsigned long)addr, sizeof(val));
+       void *addrs[1] = { (void *)addr };
+       u32 insns[1] = { (u32)val };
+
+       BUG_ON(fn_aarch64_insn_patch_text(addrs, insns, 1));
 }
 
 void arch_kp_core_arm(struct kp_core *p)
@@ -548,6 +555,14 @@ EXPORT_SYMBOL_GPL(set_jump_cb);
  */
 int arch_init_module_deps(void)
 {
+       const char *sym = "aarch64_insn_patch_text";
+
+       fn_aarch64_insn_patch_text = (void *)swap_ksyms(sym);
+       if (!fn_aarch64_insn_patch_text) {
+               pr_err("Symbol '%s' not found\n", sym);
+               return -ESRCH;
+       }
+
        return 0;
 }