From 7b0bd10c0b83cf88ef5676d54d1c927c3ea57436 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Fri, 13 Apr 2018 14:17:10 +0100 Subject: [PATCH] ring0 priviledged actions --- kernel_module/README.adoc | 4 ++- kernel_module/pci.c | 2 +- kernel_module/ring0.c | 33 ++++++++++++++++++++++ kernel_module/ring0.h | 56 ++++++++++++++++++++++++++++++++++++++ kernel_module/user/ring0.c | 18 ++++++++++++ 5 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 kernel_module/ring0.c create mode 100644 kernel_module/ring0.h create mode 100644 kernel_module/user/ring0.c diff --git a/kernel_module/README.adoc b/kernel_module/README.adoc index 57636f4..f78d140 100644 --- a/kernel_module/README.adoc +++ b/kernel_module/README.adoc @@ -37,7 +37,9 @@ .. link:character_device_create.c[] .. link:virt_to_phys.c[] . Utilities -.. kstrto +.. link:kstrto.c[] +. Misc +.. link:ring0.c[] . Hardware device drivers .. link:pci_min.c[] .. link:pci.c[] diff --git a/kernel_module/pci.c b/kernel_module/pci.c index 3e43c79..a89f9ca 100644 --- a/kernel_module/pci.c +++ b/kernel_module/pci.c @@ -1,5 +1,5 @@ /* -Only teted for x86. +Only tested for x86. Usage: diff --git a/kernel_module/ring0.c b/kernel_module/ring0.c new file mode 100644 index 0000000..8f7479f --- /dev/null +++ b/kernel_module/ring0.c @@ -0,0 +1,33 @@ +/* +This illustrates operations which are only possible in ring 0. +https://stackoverflow.com/questions/7415515/how-to-access-the-control-registers-cr0-cr2-cr3-from-a-program-getting-segmenta/7419306#7419306 + +It only works for x86_64. + +Then try to run this on userland and see the process be killed: + + /ring0.out +*/ + +#include +#include + +#include "ring0.h" + +static int myinit(void) +{ +#if defined(__x86_64__) || defined(__i386__) + Ring0Regs ring0_regs; + ring0_get_control_regs(&ring0_regs); + pr_info("cr0 = 0x%8.8llX\n", (unsigned long long)ring0_regs.cr0); + pr_info("cr2 = 0x%8.8llX\n", (unsigned long long)ring0_regs.cr2); + pr_info("cr3 = 0x%8.8llX\n", (unsigned long long)ring0_regs.cr3); +#endif + return 0; +} + +static void myexit(void) {} + +module_init(myinit) +module_exit(myexit) +MODULE_LICENSE("GPL"); diff --git a/kernel_module/ring0.h b/kernel_module/ring0.h new file mode 100644 index 0000000..d2aa361 --- /dev/null +++ b/kernel_module/ring0.h @@ -0,0 +1,56 @@ +#if defined(__x86_64__) || defined(__i386__) + +#ifdef THIS_MODULE +#include +#if defined(__x86_64__) +typedef u64 T; +#elif defined(__i386__) +typedef u32 T; +#endif +#else +#include +#if defined(__x86_64__) +typedef uint64_t T; +#elif defined(__i386__) +typedef uint32_t T; +#endif +#endif + +typedef struct { + T cr0; + T cr2; + T cr3; +} Ring0Regs; + +void ring0_get_control_regs(Ring0Regs *ring0_regs) +{ +#ifdef __x86_64__ + __asm__ __volatile__ ( + "mov %%cr0, %%rax\n\t" + "mov %%eax, %0\n\t" + "mov %%cr2, %%rax\n\t" + "mov %%eax, %1\n\t" + "mov %%cr3, %%rax\n\t" + "mov %%eax, %2\n\t" + : "=m" (ring0_regs->cr0), + "=m" (ring0_regs->cr2), + "=m" (ring0_regs->cr3) + : /* no input */ + : "%rax" + ); +#elif defined(__i386__) + __asm__ __volatile__ ( + "mov %%cr0, %%eax\n\t" + "mov %%eax, %0\n\t" + "mov %%cr2, %%eax\n\t" + "mov %%eax, %1\n\t" + "mov %%cr3, %%eax\n\t" + "mov %%eax, %2\n\t" + : "=m" (ring0_regs->cr0), + "=m" (ring0_regs->cr2), + "=m" (ring0_regs->cr3) + : /* no input */ + : "%eax" + ); +#endif +} diff --git a/kernel_module/user/ring0.c b/kernel_module/user/ring0.c new file mode 100644 index 0000000..8687d97 --- /dev/null +++ b/kernel_module/user/ring0.c @@ -0,0 +1,18 @@ +/* +See ../ring0.c + +This executable is expected to segfault. +*/ + +#include +#include + +#include "../ring0.h" + +int main(void) { +#if defined(__x86_64__) || defined(__i386__) + Ring0Regs ring0_regs; + ring0_get_control_regs(&ring0_regs); +#endif + return EXIT_SUCCESS; +}