#include <ksyms/ksyms.h>
-static unsigned long get_init_mm(void)
-{
- static unsigned long addr = 0;
-
- if (addr == 0)
- addr = swap_ksyms("init_mm");
+static struct mm_struct *swap_init_mm = NULL;
+static int (*swap_set_memory_ro)(unsigned long addr, int numpages) = NULL;
+static int (*swap_set_memory_rw)(unsigned long addr, int numpages) = NULL;
- return addr;
-}
static int get_pte_cb(pte_t *ptep, pgtable_t token,
unsigned long addr, void *data)
static pte_t get_pte(unsigned long page_addr)
{
- struct mm_struct *mm = (struct mm_struct *)get_init_mm();
pte_t pte = 0;
- apply_to_page_range(mm, page_addr, PAGE_SIZE, get_pte_cb, &pte);
+ apply_to_page_range(swap_init_mm, page_addr,
+ PAGE_SIZE, get_pte_cb, &pte);
return pte;
}
DEFINE_SPINLOCK(mem_lock);
spin_lock_irqsave(&mem_lock, flags);
- set_memory_rw(page_addr, 1);
- *maddr = val;
- set_memory_ro(page_addr, 1);
+ if (swap_set_memory_rw(page_addr, 1) == 0) {
+ *maddr = val;
+ swap_set_memory_ro(page_addr, 1);
+ } else {
+ printk("RWX: failed to write memory %08lx (%08lx)\n",
+ addr, val);
+ }
spin_unlock_irqrestore(&mem_lock, flags);
} else {
*maddr = val;
write_to_module(addr, val);
}
}
+
+int mem_rwx_init(void)
+{
+ const char *sym;
+
+ sym = "set_memory_ro";
+ swap_set_memory_ro = (void *)swap_ksyms(sym);
+ if (swap_set_memory_ro == NULL)
+ goto not_found;
+
+ sym = "set_memory_rw";
+ swap_set_memory_rw = (void *)swap_ksyms(sym);
+ if (swap_set_memory_rw == NULL)
+ goto not_found;
+
+ sym = "init_mm";
+ swap_init_mm = (void *)swap_ksyms(sym);
+ if (swap_init_mm == NULL)
+ goto not_found;
+
+ return 0;
+
+not_found:
+ printk("ERROR: symbol '%s' not found\n", sym);
+ return -ESRCH;
+}
{
int ret;
+#ifdef CONFIG_STRICT_MEMORY_RWX
+ ret = mem_rwx_init();
+ if (ret)
+ return ret;
+#endif /* CONFIG_STRICT_MEMORY_RWX */
+
// Register hooks (kprobe_handler)
__swap_register_undef_hook = (void *)swap_ksyms("register_undef_hook");
if (__swap_register_undef_hook == NULL) {
{
kjump_exit();
swap_unregister_undef_hook(&undef_ho_k);
+
+#ifdef CONFIG_STRICT_MEMORY_RWX
+ mem_rwx_exit();
+#endif /* CONFIG_STRICT_MEMORY_RWX */
}
/* export symbol for trampoline_arm.h */