diff options
author | Andy Lutomirski <luto@kernel.org> | 2015-04-17 14:05:54 -0700 |
---|---|---|
committer | Andy Lutomirski <luto@kernel.org> | 2015-04-17 14:16:00 -0700 |
commit | f67708ab5f6432af863b3fa3f405bd120c492fb7 (patch) | |
tree | e3acb94766601ad1afe057c5894f8410dc075639 | |
parent | 6522dfcac5dfbf2ad31920d529a2a42d57359b6f (diff) | |
download | misc-tests-f67708ab5f6432af863b3fa3f405bd120c492fb7.tar.gz |
gsbase: new test
Signed-off-by: Andy Lutomirski <luto@kernel.org>
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | gsbase.c | 79 |
3 files changed, 81 insertions, 1 deletions
@@ -7,6 +7,7 @@ user_visible_state highsys null_seccomp segregs +gsbase *~ *_32 *_64 @@ -1,6 +1,6 @@ .PHONY: all clean -SIMPLE_C_TARGETS := dump-vsyscall context_switch_latency kernel_pf user_visible_state null_seccomp highsys +SIMPLE_C_TARGETS := dump-vsyscall context_switch_latency kernel_pf user_visible_state null_seccomp highsys gsbase SIMPLE_CC_TARGETS := evil-clock-test diff --git a/gsbase.c b/gsbase.c new file mode 100644 index 0000000..87e4407 --- /dev/null +++ b/gsbase.c @@ -0,0 +1,79 @@ +/* + * gsbase.c, a gsbase test + * Copyright (c) 2014 Andy Lutomirski + * GPL v2 + */ + +#include <stdio.h> +#include <stdbool.h> +#include <sys/syscall.h> +#include <unistd.h> +#include <err.h> +#include <sys/user.h> +#include <asm/prctl.h> +#include <sys/prctl.h> +#include <sys/mman.h> + +#ifndef __x86_64__ +# error This test is 64-bit only +#endif + +static unsigned char *testptr, *testptr2; + +static unsigned char read_gs_testvals(void) +{ + unsigned char ret; + asm volatile ("movb %%gs:%1, %0" : "=r" (ret) : "m" (*testptr)); + return ret; +} + +int main() +{ + int errors = 0; + + testptr = mmap((void *)0x200000000UL, 1, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0); + if (testptr == MAP_FAILED) + err(1, "mmap"); + + testptr2 = mmap((void *)0x300000000UL, 1, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0); + if (testptr2 == MAP_FAILED) + err(1, "mmap"); + + *testptr = 0; + *testptr2 = 1; + + if (syscall(SYS_arch_prctl, ARCH_SET_GS, + (unsigned long)testptr2 - (unsigned long)testptr) != 0) + err(1, "ARCH_SET_GS"); + + usleep(100); + + if (read_gs_testvals() == 1) { + printf("[OK]\tARCH_SET_GS worked\n"); + } else { + printf("[FAIL]\tARCH_SET_GS failed\n"); + errors++; + } + + asm volatile ("mov %0,%%gs" : : "r" (0)); + + if (read_gs_testvals() == 0) { + printf("[OK]\tWriting 0 to gs worked\n"); + } else { + printf("[FAIL]\tWriting 0 to gs failed\n"); + errors++; + } + + usleep(100); + + if (read_gs_testvals() == 0) { + printf("[OK]\tgsbase is still zero\n"); + } else { + printf("[FAIL]\tgsbase reset itself to 1\n"); + errors++; + } + + return errors == 0 ? 0 : 1; +} |