/* * this program tells if an ELF has a PT_GNU_STACK marker, and can set it to rw so that it can be loaded in a PaX-enhanced kernel * * Author: Yoann Guillot, 03/2007 * Licence: public domain */ #include #include #include #include #include #include #include typedef struct { unsigned long p_type; unsigned long p_offset; unsigned long p_vaddr; unsigned long p_paddr; unsigned long p_filesz; unsigned long p_memsz; unsigned long p_flags; unsigned long p_align; } phdr; int main(int argc, char **argv) { if (argc < 2) { fprintf(stderr, "usage: fix [--checkonly] \n"); exit(1); } int justsee = (argc > 2); printf("%s: ", argv[argc-1]); int fd = open(argv[argc-1], (justsee ? O_RDONLY : O_RDWR)); if (fd == -1) { perror("open"); exit(1); } unsigned long len = lseek(fd, 0, SEEK_END); char *ptr = mmap(0, len, PROT_READ | (justsee ? 0 : PROT_WRITE), MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap"); exit(1); } close(fd); if (memcmp(ptr, "\x7f" "ELF", 4)) { printf("not an ELF file\n"); exit(0); } unsigned long off; if (!(off = *(unsigned long*)(ptr + 28))) { printf("not an executable ELF\n"); exit(0); } len = *(unsigned short*)(ptr + 44); unsigned long i; int found = 0; phdr *hdr = (phdr*)(ptr + off); for (i=0 ; i