├── Makefile ├── README.md ├── enable_rdfsbase.c ├── install.sh └── uninstall.sh /Makefile: -------------------------------------------------------------------------------- 1 | obj-m += enable_rdfsbase.o 2 | 3 | KERNEL_MAKE := $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) 4 | 5 | all: 6 | $(KERNEL_MAKE) modules 7 | 8 | # Use install and uninstall targets for debug and developement purpose 9 | install: 10 | sudo insmod enable_rdfsbase.ko 11 | 12 | uninstall: 13 | sudo rmmod enable_rdfsbase.ko 14 | 15 | clean: 16 | $(KERNEL_MAKE) clean 17 | $(RM) *.o.ur-safe 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **SECURITY NOTICE: This kernel module is intended for evaluation only, NOT in production!** Enabling `rdfsbase`-family instructions in the way shown in this kernel module creates a full unpriviledged root hole in the Linux kernel. The Linux kernel community is actively working on a patchset that does `rdfsbase` enabling in a secure way. And hopefully, we shall see the patchset merged in the near future. For more information, see [a LWN post on FSGSBASE patch series](https://lwn.net/Articles/821723/) and [discussions about the patchset on Linux mailing list](https://lwn.net/ml/linux-kernel/20200511045311.4785-1-sashal@kernel.org/). 2 | 3 | # Introduction 4 | 5 | This is a Linux kernel module that enables RDFSBASE, WRFSBASE, RDGSBASE, WRGSBASE instructions on x86. These instructions are disabled by default on Linux. They can be enabled by setting the 16th bit of CR4, i.e., CR4.FSGSBASE. 6 | 7 | # How to Build 8 | 9 | To compile the kernel module, run the following command 10 | 11 | make 12 | 13 | To enable RDFSBASE instruction and its friends until the next OS reboot, run the following command 14 | 15 | make install 16 | 17 | To disable RDFSBASE instruction and its friends until the next OS reboot, run the following command 18 | 19 | make uninstall 20 | 21 | # How to Install 22 | 23 | To enable RDFSBASE permanently (i.e., enabled even after the next OS reboot), run 24 | 25 | ./install.sh 26 | 27 | To uninstall, run 28 | 29 | ./uninstall.sh 30 | 31 | # Kernel Compatibility 32 | 33 | This code has been tested with Linux kernel 4.15. It may or may not work with newer or older versions of Linux kernel. 34 | -------------------------------------------------------------------------------- /enable_rdfsbase.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ 2 | /* 3 | * A kernel module to enable RDFSBASE family instructions on x86. 4 | * 5 | * Copyright (c) 2018-2019 Intel Corp. All rights reserved. 6 | * Author: Hongliang Tian 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define LOG(...) printk(KERN_INFO "enable_rdfsbase: " __VA_ARGS__) 18 | 19 | #define CR4_FSGSBASE_BIT (16) 20 | #define CR4_FSGSBASE_MASK (1UL << CR4_FSGSBASE_BIT) 21 | 22 | 23 | static void set_cr4_fsgsbase(void *_unused) 24 | { 25 | #if KERNEL_VERSION(4, 0, 0) <= LINUX_VERSION_CODE 26 | cr4_set_bits(CR4_FSGSBASE_MASK); 27 | #else 28 | unsigned long cr4_val; 29 | 30 | cr4_val = read_cr4(); 31 | if ((cr4_val | CR4_FSGSBASE_MASK) != cr4_val) { 32 | cr4_val |= CR4_FSGSBASE_MASK; 33 | write_cr4(cr4_val); 34 | } 35 | #endif 36 | } 37 | 38 | static void clear_cr4_fsgsbase(void *_unused) 39 | { 40 | #if KERNEL_VERSION(4, 0, 0) <= LINUX_VERSION_CODE 41 | cr4_clear_bits(CR4_FSGSBASE_MASK); 42 | #else 43 | unsigned long cr4_val; 44 | 45 | cr4_val = read_cr4(); 46 | if ((cr4_val & ~CR4_FSGSBASE_MASK) != cr4_val) { 47 | cr4_val &= ~CR4_FSGSBASE_MASK; 48 | write_cr4(cr4_val); 49 | } 50 | #endif 51 | } 52 | 53 | int __init enable_rdfsbase_init(void) 54 | { 55 | int cpu; 56 | int err; 57 | 58 | LOG("Loaded\n"); 59 | 60 | if (!boot_cpu_has(X86_FEATURE_FSGSBASE)) { 61 | LOG("FSGSBASE feature is not supported by this CPU!\n"); 62 | return -ENODEV; 63 | } 64 | 65 | for_each_online_cpu(cpu) { 66 | err = smp_call_function_single(cpu, set_cr4_fsgsbase, NULL, 1); 67 | 68 | if (err) 69 | LOG("Fail to set CR4.FSGSBASE on CPU %d\n", cpu); 70 | else 71 | LOG("RDFSBASE and its friends are now enabled on CPU %d\n", cpu); 72 | } 73 | 74 | return 0; 75 | } 76 | 77 | void __exit enable_rdfsbase_exit(void) 78 | { 79 | int cpu; 80 | int err; 81 | 82 | for_each_online_cpu(cpu) { 83 | err = smp_call_function_single(cpu, clear_cr4_fsgsbase, NULL, 1); 84 | 85 | if (err) 86 | LOG("Fail to clear CR4.FSGSBASE on CPU %d\n", cpu); 87 | else 88 | LOG("RDFSBASE and its friends are now disabled on CPU %d\n", cpu); 89 | } 90 | 91 | LOG("Unloaded\n"); 92 | } 93 | 94 | module_init(enable_rdfsbase_init); 95 | module_exit(enable_rdfsbase_exit); 96 | 97 | MODULE_LICENSE("Dual BSD/GPL"); 98 | MODULE_AUTHOR("Hongliang Tian, Intel Corp."); 99 | MODULE_DESCRIPTION("Enable RDFSBASE family instructions on x86"); 100 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo mkdir -p "/lib/modules/"`uname -r`"/kernel/drivers/occlum" 4 | sudo cp enable_rdfsbase.ko "/lib/modules/"`uname -r`"/kernel/drivers/occlum" 5 | 6 | if [ -e "/etc/modules" ]; then 7 | # Ubuntu 8 | sudo sh -c "cat /etc/modules | grep -Fxq enable_rdfsbase || echo enable_rdfsbase >> /etc/modules" 9 | elif [ -d "/etc/modules-load.d" ]; then 10 | # CentOS 11 | sudo sh -c "echo \"enable_rdfsbase\" > /etc/modules-load.d/enable_rdfsbase.conf" 12 | fi 13 | sudo /sbin/depmod 14 | sudo /sbin/modprobe enable_rdfsbase 15 | -------------------------------------------------------------------------------- /uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | sudo /sbin/modprobe -r enable_rdfsbase 4 | sudo rm -rf "/lib/modules/"`uname -r`"/kernel/drivers/occlum" 5 | sudo /sbin/depmod 6 | if [ -e "/etc/modules" ]; then 7 | # Ubuntu 8 | sudo /bin/sed -i '/^enable_rdfsbase$/d' /etc/modules 9 | elif [ -d "/etc/modules-load.d" ]; then 10 | # CentOS 11 | sudo rm -f /etc/modules-load.d/enable_rdfsbase.conf 12 | fi 13 | --------------------------------------------------------------------------------