Search code examples
linuxmemorymodulekernel

Sharing memory from kernel to user space by disabling the "Write Protect Bit (CR0:16)"


If I have my own kernel space memory manager, is it theoretically possible to share a memory pointer allocated by a kernel module to a user space application by disabling the "Write Protect Bit (CR0:16)" using read_cr0() and write_cr0() thus allowing read/write access to the entire system memory space?

(This is for embedded devices where we "trust" our own processes)


Solution

  • I just experimented on my own computer but to answer my own question: NO, it is not possible to share the kernel's memory directly with a user space process.

    I did try to write my own kernel module based on Tempesta's stack-like region-based memory manager (pool.c):

    [...]
    
    static int __init
    tfw_pool_init(void)
    {
        printk(KERN_ALERT "HIJACK INIT\n");
        write_cr0 (read_cr0 () & (~ 0x10000));
    
        pg_cache = alloc_percpu(unsigned long [TFW_POOL_PGCACHE_SZ]);
        if (pg_cache == NULL)
            return -ENOMEM;
    
        printk(KERN_NOTICE "__tfw_pool_new = %p\n", __tfw_pool_new);
        printk(KERN_NOTICE "tfw_pool_alloc = %p\n", tfw_pool_alloc);
        printk(KERN_NOTICE "tfw_pool_realloc = %p\n", tfw_pool_realloc);
        printk(KERN_NOTICE "tfw_pool_free = %p\n", tfw_pool_free);
        printk(KERN_NOTICE "tfw_pool_destroy = %p\n", tfw_pool_destroy);
    
        return 0;
    }
    
    static void __exit
    tfw_pool_exit(void)
    {
        free_percpu(pg_cache);
    
        write_cr0 (read_cr0 () | 0x10000);
        printk(KERN_ALERT "MODULE EXIT\n");
    }
    
    module_init(tfw_pool_init);
    module_exit(tfw_pool_exit);
    MODULE_LICENSE("GPL");
    

    And not only calling the functions printed out segfaults but my system became highly unstable after loading the module so DO NOT TRY THIS AT HOME.