Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 27 additions & 45 deletions module.c
Original file line number Diff line number Diff line change
@@ -1,63 +1,45 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kallsyms.h>
#include <linux/slab.h>

#if defined __i386__
#define ASM_HOOK_CODE "\x68\x00\x00\x00\x00\xc3" // push 0x00000000, ret
#define ASM_HOOK_CODE_OFFSET 1
#elif defined __x86_64__
#define ASM_HOOK_CODE "\x48\xb8\x00\x00\x00\x00\x00\x00\x00\x00\xff\xe0" // mov rax 0x0000000000000000, jmp rax
#define ASM_HOOK_CODE_OFFSET 2
#else
#error ARCH_ERROR_MESSAGE
#endif

static void *original_devmem_function = NULL;
static char original_function_code_backup[sizeof(ASM_HOOK_CODE) - 1];
#include <linux/livepatch.h>

#include <linux/seq_file.h>


int modified_devmem_function(unsigned long pagenr)
{
return 1;
}

int init_module(void)
{
original_devmem_function = (void *)kallsyms_lookup_name("devmem_is_allowed");
if (!original_devmem_function)
static struct klp_func funcs[] = {
{
printk(KERN_INFO "Can't locate the needed symbol, is it exported?\n");
return -1;
}
.old_name = "devmem_is_allowed",
.new_func = modified_devmem_function,
}, { }
};

preempt_disable();
write_cr0(read_cr0() & (~0x10000)); //disable write-protected memory

memcpy(original_function_code_backup, original_devmem_function, sizeof(ASM_HOOK_CODE) - 1);
memcpy(original_devmem_function, ASM_HOOK_CODE, sizeof(ASM_HOOK_CODE) - 1);
*(void **)&((char *)original_devmem_function)[ASM_HOOK_CODE_OFFSET] = modified_devmem_function;
static struct klp_object objs[] = {
{
/* name being NULL means vmlinux */
.funcs = funcs,
}, { }
};

write_cr0(read_cr0() | 0x10000); // enable write-protected memory
preempt_enable();
static struct klp_patch patch = {
.mod = THIS_MODULE,
.objs = objs,
};

printk(KERN_INFO "Memory access module loaded\n");
return 0;
static int livepatch_init(void)
{
return klp_enable_patch(&patch);
}

void cleanup_module(void)
static void livepatch_exit(void)
{
preempt_disable();
write_cr0(read_cr0() & (~0x10000)); //disable write-protected memory

memcpy(original_devmem_function, original_function_code_backup, sizeof(ASM_HOOK_CODE) - 1);

write_cr0(read_cr0() | 0x10000); // enable write-protected memory
preempt_enable();

printk(KERN_INFO "Memory access module unloaded\n");
}

MODULE_AUTHOR("Ozgun Ayaz");
MODULE_DESCRIPTION("make /dev/mem writable beyond the first 1 MB");
module_init(livepatch_init);
module_exit(livepatch_exit);
MODULE_LICENSE("GPL");
MODULE_INFO(intree, "Y"); //bullshit lol
MODULE_DESCRIPTION("make /dev/mem writable beyond the first 1 MB");
MODULE_INFO(livepatch, "Y");