/* * check whether w^x works as one cannot trust /proc//maps * 2006,2007 lnussel@suse.de, GPL */ #include #include #include #include #include #include static sigjmp_buf jmpbuf; void segvhandler(int signum) { siglongjmp(jmpbuf, 1); } static char staticbuf[] = #if __i386__ "\xc7\x00\x01\x00\x00\x00" // movl $0x1,(%eax) "\xff\xe3" // jmp *%ebx #else "\x48\xc7\x00\x01\x00\x00\x00" // movq $0x1,(%rax) "\xff\xe3" // jmpq *%rbx #endif "\x90\x90\x90\x90"; // some padding int main(int argc, char* argv[]) { int verbose = 1; int flag = 0; unsigned nonxbits = 0; char stackbuf[sizeof(staticbuf)]; long bufaddr[4]; char* bufnames[4] = { "static", "stack", "heap", "verify" }; int i; if(argc > 1 && !strcmp(argv[1], "-q")) verbose = 0; if(verbose) puts("If you see any segfault something went wrong."); bufaddr[0] = (long)staticbuf; bufaddr[1] = (long)stackbuf; bufaddr[2] = (long)malloc(sizeof(staticbuf)); bufaddr[3] = (long)mmap(0, sizeof(staticbuf), PROT_EXEC|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); for (i = 1; i < 4; ++i) { memcpy((void*)bufaddr[i], staticbuf, sizeof(staticbuf)); } signal(SIGSEGV, segvhandler); for (i = 0; i < 4; ++i) { flag = 0; if(!sigsetjmp(jmpbuf, 1)) { long faddr = (long)&flag; long addr = (long)&&out; __asm__ __volatile__( #if __i386__ "movl %2, %%eax\n"\ "movl %1, %%ebx\n"\ "jmp *%0\n" \ : : "m"(bufaddr[i]), "m"(addr), "m"(faddr) : "%eax", "%ebx" #else "movq %2, %%rax\n"\ "movq %1, %%rbx\n"\ "jmp *%0\n" \ : : "m"(bufaddr[i]), "m"(addr), "m"(faddr) : "%rax", "%rbx" #endif ); } out: nonxbits |= flag<