diff options
author | Andy Lutomirski <luto@kernel.org> | 2015-04-17 14:15:12 -0700 |
---|---|---|
committer | Andy Lutomirski <luto@kernel.org> | 2015-04-17 14:16:00 -0700 |
commit | b4c19321394d0de16282ea0a02f53af0643ee25c (patch) | |
tree | 3f26aeade11de0c9ff79c484e4e1376bb377e626 | |
parent | 8620bdbb677df38eb93494cff46cd7179dec0a21 (diff) | |
download | misc-tests-b4c19321394d0de16282ea0a02f53af0643ee25c.tar.gz |
ntflag: New test
Signed-off-by: Andy Lutomirski <luto@kernel.org>
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | ntflag.c | 54 |
2 files changed, 55 insertions, 1 deletions
@@ -4,7 +4,7 @@ SIMPLE_C_TARGETS := dump-vsyscall context_switch_latency kernel_pf user_visible_ SIMPLE_CC_TARGETS := evil-clock-test -SPLIT_C_TARGETS := dump-vdso dump-vvar syscall_exit_regs dump_all_pmcs +SPLIT_C_TARGETS := dump-vdso dump-vvar syscall_exit_regs dump_all_pmcs ntflag SPLIT_CC_TARGETS := timing_test test_vsyscall test_vdso_parser ALL_TARGETS := $(SIMPLE_C_TARGETS) $(SIMPLE_CC_TARGETS) $(SPLIT_C_TARGETS:%=%_64) $(SPLIT_CC_TARGETS:%=%_64) $(SPLIT_C_TARGETS:%=%_32) $(SPLIT_CC_TARGETS:%=%_32) syscall32_from_64 segregs diff --git a/ntflag.c b/ntflag.c new file mode 100644 index 0000000..b2233f4 --- /dev/null +++ b/ntflag.c @@ -0,0 +1,54 @@ +/* + * single_step_syscall.c - single-steps various x86 syscalls + * Copyright (c) 2014-2015 Andrew Lutomirski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Some obscure user-space code requires the ability to make system calls + * with FLAGS.NT set. Make sure it works. + */ + +#include <stdio.h> +#include <unistd.h> +#include <sys/syscall.h> +#include <asm/processor-flags.h> + +#ifdef __x86_64__ +# define WIDTH "q" +#else +# define WIDTH "l" +#endif + +static unsigned long get_eflags(void) +{ + unsigned long eflags; + asm volatile ("pushf" WIDTH "\n\tpop" WIDTH " %0" : "=rm" (eflags)); + return eflags; +} + +static void set_eflags(unsigned long eflags) +{ + asm volatile ("push" WIDTH " %0\n\tpopf" WIDTH + : : "rm" (eflags) : "flags"); +} + +int main() +{ + printf("[RUN]\tSet NT and issue a syscall\n"); + set_eflags(get_eflags() | X86_EFLAGS_NT); + syscall(SYS_getpid); + if (get_eflags() & X86_EFLAGS_NT) { + printf("[OK]\tThe syscall worked and NT is still set\n"); + return 0; + } else { + printf("[FAIL]\tThe syscall worked but NT was cleared\n"); + return 1; + } +} |