1a9c909ceSAndy Lutomirski /* 2a9c909ceSAndy Lutomirski * syscall_nt.c - checks syscalls with NT set 3a9c909ceSAndy Lutomirski * Copyright (c) 2014-2015 Andrew Lutomirski 4a9c909ceSAndy Lutomirski * 5a9c909ceSAndy Lutomirski * This program is free software; you can redistribute it and/or modify 6a9c909ceSAndy Lutomirski * it under the terms and conditions of the GNU General Public License, 7a9c909ceSAndy Lutomirski * version 2, as published by the Free Software Foundation. 8a9c909ceSAndy Lutomirski * 9a9c909ceSAndy Lutomirski * This program is distributed in the hope it will be useful, but 10a9c909ceSAndy Lutomirski * WITHOUT ANY WARRANTY; without even the implied warranty of 11a9c909ceSAndy Lutomirski * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12a9c909ceSAndy Lutomirski * General Public License for more details. 13a9c909ceSAndy Lutomirski * 14a9c909ceSAndy Lutomirski * Some obscure user-space code requires the ability to make system calls 15a9c909ceSAndy Lutomirski * with FLAGS.NT set. Make sure it works. 16a9c909ceSAndy Lutomirski */ 17a9c909ceSAndy Lutomirski 18a9c909ceSAndy Lutomirski #include <stdio.h> 19a9c909ceSAndy Lutomirski #include <unistd.h> 20a9c909ceSAndy Lutomirski #include <sys/syscall.h> 21a9c909ceSAndy Lutomirski #include <asm/processor-flags.h> 22a9c909ceSAndy Lutomirski 23a9c909ceSAndy Lutomirski #ifdef __x86_64__ 24a9c909ceSAndy Lutomirski # define WIDTH "q" 25a9c909ceSAndy Lutomirski #else 26a9c909ceSAndy Lutomirski # define WIDTH "l" 27a9c909ceSAndy Lutomirski #endif 28a9c909ceSAndy Lutomirski 29a9c909ceSAndy Lutomirski static unsigned long get_eflags(void) 30a9c909ceSAndy Lutomirski { 31a9c909ceSAndy Lutomirski unsigned long eflags; 32a9c909ceSAndy Lutomirski asm volatile ("pushf" WIDTH "\n\tpop" WIDTH " %0" : "=rm" (eflags)); 33a9c909ceSAndy Lutomirski return eflags; 34a9c909ceSAndy Lutomirski } 35a9c909ceSAndy Lutomirski 36a9c909ceSAndy Lutomirski static void set_eflags(unsigned long eflags) 37a9c909ceSAndy Lutomirski { 38a9c909ceSAndy Lutomirski asm volatile ("push" WIDTH " %0\n\tpopf" WIDTH 39a9c909ceSAndy Lutomirski : : "rm" (eflags) : "flags"); 40a9c909ceSAndy Lutomirski } 41a9c909ceSAndy Lutomirski 42a9c909ceSAndy Lutomirski int main() 43a9c909ceSAndy Lutomirski { 44a9c909ceSAndy Lutomirski printf("[RUN]\tSet NT and issue a syscall\n"); 45a9c909ceSAndy Lutomirski set_eflags(get_eflags() | X86_EFLAGS_NT); 46a9c909ceSAndy Lutomirski syscall(SYS_getpid); 47a9c909ceSAndy Lutomirski if (get_eflags() & X86_EFLAGS_NT) { 48a9c909ceSAndy Lutomirski printf("[OK]\tThe syscall worked and NT is still set\n"); 49a9c909ceSAndy Lutomirski return 0; 50a9c909ceSAndy Lutomirski } else { 51a9c909ceSAndy Lutomirski printf("[FAIL]\tThe syscall worked but NT was cleared\n"); 52a9c909ceSAndy Lutomirski return 1; 53a9c909ceSAndy Lutomirski } 54a9c909ceSAndy Lutomirski } 55