/* skas_or_tt Copyright (C) 2003 Jonathan Rosenbaum A program to check for the existence of the skas patch in the host kernel and /proc/mm. Basically borrowed/simplified from jdike's process.c. This is a good way to learn about clone() and ptrace(). */ #include #include #include #include #include /* for mmap */ #include #include #include /* clone */ #define PTRACE_FAULTINFO 52 #define PAGE_SIZE 1024 int main(void) { int n, pid, ret = 1; void *stack; struct ptrace_faultinfo { int is_write; unsigned long addr; }; struct ptrace_faultinfo fi; printf("Checking for the skas3 patch in the host..."); pid = start_ptraced_child(&stack); n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); if(n < 0){ if(errno == EIO) printf("not found\n"); else printf("No (unexpected errno - %d)\n", errno); ret = 0; } else printf("found\n"); printf("Checking for /proc/mm..."); if(access("/proc/mm", W_OK)){ printf("not found\n"); ret = 0; } else printf("found\n"); kill(pid, SIGKILL); return(ret); } int threadFunction( void* argument ) { printf( "child thread exiting\n" ); exit(0); } int os_getpid(void) { return(getpid()); } void os_stop_process(int pid) { kill(pid, SIGSTOP); } void os_kill_process(int pid, int reap_child) { kill(pid, SIGKILL); if(reap_child) waitpid(pid, NULL, 0); } static int ptrace_child(void *arg) { int pid = os_getpid(); if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ perror("ptrace"); os_kill_process(pid, 0); } os_stop_process(pid); _exit(os_getpid() == pid); } int start_ptraced_child(void **stack_out) { void *stack; unsigned long sp; int pid, n, status; stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if(stack == MAP_FAILED) printf("check_ptrace : mmap failed, errno = %d", errno); sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); if(pid < 0) { printf("check_ptrace : clone failed, errno = %d\n", errno); exit(0); } n = waitpid(pid, &status, WUNTRACED); if(n < 0) { printf("check_ptrace : wait failed, errno = %d\n", errno); exit(0); } if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) { printf("check_ptrace : expected SIGSTOP, got status = %d\n", status); exit(0); } *stack_out = stack; return(pid); } /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only. This must remain at the end * of the file. * --------------------------------------------------------------------------- * Local variables: * c-file-style: "linux" * End: */