diff -urp paxctl-0.3/ChangeLog paxctl-0.4/ChangeLog --- paxctl-0.3/ChangeLog 2005-05-03 20:04:30.000000000 +0100 +++ paxctl-0.4/ChangeLog 2005-05-29 13:01:11.000000000 +0100 @@ -1,3 +1,6 @@ +2005.05.29 PaX Team > + cleaned up error code reporting, thanks to Kevin F. Quinn + 2005.05.03 PaX Team > added -c option to convert PT_GNU_STACK into PT_PAX_FLAGS minor typo fixes in the code/manpage diff -urp paxctl-0.3/Makefile paxctl-0.4/Makefile --- paxctl-0.3/Makefile 2004-02-25 15:20:44.000000000 +0000 +++ paxctl-0.4/Makefile 2005-05-29 12:46:27.000000000 +0100 @@ -1,8 +1,8 @@ CC:=gcc CP:=cp -CFLAGS:=-Wall -W -O2# -fPIC +CFLAGS:=-O2 -Wall -W -Wcast-qual -Wcast-align -Wbad-function-cast -Wsign-compare -Wshadow -Wwrite-strings -Wnested-externs -Winline -Wredundant-decls -Waggregate-return -Wno-format-y2k -Wno-format-extra-args -Wformat-nonliteral -Wformat-security -Wformat=2 -Wdisabled-optimization -Werror -Wpointer-arith -Wconversion -Wmissing-declarations -Wmissing-prototypes -Wunreachable-code DESTDIR:= -LDFLAGS:=#-Wl,-pie +LDFLAGS:= MANDIR:=/usr/share/man/man1 MKDIR:=mkdir -p PROG:=paxctl diff -urp paxctl-0.3/paxctl.c paxctl-0.4/paxctl.c --- paxctl-0.3/paxctl.c 2005-05-03 21:11:06.000000000 +0100 +++ paxctl-0.4/paxctl.c 2005-05-29 13:03:37.000000000 +0100 @@ -64,7 +64,7 @@ static void * elf32_map_phdr(const int f return mmap(NULL, size, flags, MAP_SHARED, fd, (off_t)0); } -static void elf32_modify_phdr(unsigned char * const map, const struct pax_state * const state) +static int elf32_modify_phdr(unsigned char * const map, const struct pax_state * const state) { unsigned int i, gnu_stack = state->ops->phnum._32, pax_flags = state->ops->phnum._32; Elf32_Phdr * const phdr = (Elf32_Phdr *)(map + state->ops->phoff._32); @@ -81,7 +81,7 @@ static void elf32_modify_phdr(unsigned c if (gnu_stack == state->ops->phnum._32) { if (!state->quiet) fprintf(stderr, "file %s does not have a PT_GNU_STACK program header, conversion failed\n", state->argv[state->files]); - return; + return EXIT_FAILURE; } phdr[gnu_stack].p_type = PT_PAX_FLAGS; phdr[gnu_stack].p_flags = PF_NORANDEXEC | PF_NOEMUTRAMP; @@ -89,7 +89,7 @@ static void elf32_modify_phdr(unsigned c } else { if (!state->quiet) fprintf(stderr, "file %s does not have a PT_PAX_FLAGS program header\n", state->argv[state->files]); - return; + return EXIT_FAILURE; } } @@ -106,6 +106,7 @@ static void elf32_modify_phdr(unsigned c phdr[pax_flags].p_flags |= state->flags_on; } } + return EXIT_SUCCESS; } static void * elf64_map_phdr(const int fd, const struct pax_state * const state) @@ -116,7 +117,7 @@ static void * elf64_map_phdr(const int f return mmap(NULL, size, flags, MAP_SHARED, fd, (off_t)0); } -static void elf64_modify_phdr(unsigned char * const map, const struct pax_state * const state) +static int elf64_modify_phdr(unsigned char * const map, const struct pax_state * const state) { unsigned int i, gnu_stack = state->ops->phnum._64, pax_flags = state->ops->phnum._64;; Elf64_Phdr * const phdr = (Elf64_Phdr *)(map + state->ops->phoff._64); @@ -133,7 +134,7 @@ static void elf64_modify_phdr(unsigned c if (gnu_stack == state->ops->phnum._64) { if (!state->quiet) fprintf(stderr, "file %s does not have a PT_GNU_STACK program header, conversion failed\n", state->argv[state->files]); - return; + return EXIT_FAILURE; } phdr[gnu_stack].p_type = PT_PAX_FLAGS; phdr[gnu_stack].p_flags = PF_NORANDEXEC | PF_NOEMUTRAMP; @@ -141,7 +142,7 @@ static void elf64_modify_phdr(unsigned c } else { if (!state->quiet) fprintf(stderr, "file %s does not have a PT_PAX_FLAGS program header\n", state->argv[state->files]); - return; + return EXIT_FAILURE; } } @@ -158,6 +159,7 @@ static void elf64_modify_phdr(unsigned c phdr[pax_flags].p_flags |= state->flags_on; } } + return EXIT_SUCCESS; } static struct elf_ops elf32 = { @@ -193,7 +195,7 @@ static void usage(void) "\t-q: suppress error messages\t-Q: report flags in short format\n" "\t-c: convert PT_GNU_STACK into PT_PAX_FLAGS (see manpage!)\n" ); - exit(EXIT_SUCCESS); + exit(EXIT_FAILURE); } static int is_elf32(const void * const map, off_t size, struct pax_state * const state) @@ -257,41 +259,41 @@ static int is_elf64(const void * const m static int pax_verify_file(struct pax_state * const state) { int fd; - const void * map; + void * map; size_t size = sizeof(Elf64_Ehdr); struct stat st; fd = open(state->argv[state->files], O_RDONLY); if (0 > fd) { if (!state->quiet) - perror("open: "); - return -1; + perror(state->argv[state->files]); + return EXIT_FAILURE; } if (-1 == fstat(fd, &st)) { close(fd); if (!state->quiet) - perror("fstat: "); - return -1; + perror(state->argv[state->files]); + return EXIT_FAILURE; } map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, (off_t)0); close(fd); if (MAP_FAILED == map) { if (!state->quiet) - perror("mmap: "); - return -1; + perror(state->argv[state->files]); + return EXIT_FAILURE; } if (st.st_size < 0 || (!is_elf32(map, st.st_size, state) && !is_elf64(map, st.st_size, state))) { - munmap((void *)map, size); + munmap(map, size); if (!state->quiet) fprintf(stderr, "file %s is not a valid ELF executable\n", state->argv[state->files]); - return -1; + return EXIT_FAILURE; } - munmap((void *)map, size); - return 0; + munmap(map, size); + return EXIT_SUCCESS; } static int pax_modify_file(const struct pax_state * const state) @@ -303,8 +305,8 @@ static int pax_modify_file(const struct fd = open(state->argv[state->files], (state->flags_on | state->flags_off | state->convert) ? O_RDWR : O_RDONLY); if (0 > fd) { if (!state->quiet) - perror("open: "); - return -1; + perror(state->argv[state->files]); + return EXIT_FAILURE; } /* mmap file */ @@ -312,36 +314,35 @@ static int pax_modify_file(const struct close(fd); if (MAP_FAILED == map) { if (!state->quiet) - perror("mmap: "); - return -1; + perror(state->argv[state->files]); + return EXIT_FAILURE; } /* report/modify flags */ - state->ops->modify_phdr(map, state); - return 0; + return state->ops->modify_phdr(map, state); } static int pax_process_file(struct pax_state * const state) { /* get/verify ELF header */ - if (0 > pax_verify_file(state)) - return -1; - - /* report/modify program header */ - if (0 > pax_modify_file(state)) - return -1; + if (EXIT_SUCCESS == pax_verify_file(state)) + /* report/modify program header */ + return pax_modify_file(state); - return 0; + return EXIT_FAILURE; } static int pax_process_files(struct pax_state * const state) { + int status = EXIT_SUCCESS; + while (state->argv[state->files]) { - pax_process_file(state); + if (EXIT_SUCCESS != pax_process_file(state)) + status = EXIT_FAILURE; ++state->files; } - return 0; + return status; } static int pax_parse_args(int argc, struct pax_state * const state) @@ -350,31 +351,31 @@ static int pax_parse_args(int argc, stru switch(getopt(argc, state->argv, "pPsSmMeErRxXvqQzc")) { case -1: state->files = optind; - return optind < argc ? 0 : -1; + return optind < argc ? EXIT_SUCCESS : EXIT_FAILURE; case '?': - return -1; + return EXIT_FAILURE; #define parse_flag(option1, option2, flag) \ - case option1: \ - state->flags_on &= ~PF_##flag; \ - state->flags_on |= PF_NO##flag; \ - state->flags_off &= ~PF_NO##flag; \ - state->flags_off |= PF_##flag; \ - break; \ - case option2: \ - state->flags_on &= ~PF_NO##flag; \ - state->flags_on |= PF_##flag; \ - state->flags_off &= ~PF_##flag; \ - state->flags_off |= PF_NO##flag; \ - break; - - parse_flag('p', 'P', PAGEEXEC); - parse_flag('s', 'S', SEGMEXEC); - parse_flag('m', 'M', MPROTECT); - parse_flag('e', 'E', EMUTRAMP); - parse_flag('r', 'R', RANDMMAP); - parse_flag('x', 'X', RANDEXEC); + case option1: \ + state->flags_on &= ~PF_##flag; \ + state->flags_on |= PF_NO##flag; \ + state->flags_off &= ~PF_NO##flag; \ + state->flags_off |= PF_##flag; \ + break; \ + case option2: \ + state->flags_on &= ~PF_NO##flag; \ + state->flags_on |= PF_##flag; \ + state->flags_off &= ~PF_##flag; \ + state->flags_off |= PF_NO##flag; \ + break; + + parse_flag('p', 'P', PAGEEXEC); + parse_flag('s', 'S', SEGMEXEC); + parse_flag('m', 'M', MPROTECT); + parse_flag('e', 'E', EMUTRAMP); + parse_flag('r', 'R', RANDMMAP); + parse_flag('x', 'X', RANDEXEC); #undef parse_flag @@ -420,15 +421,12 @@ int main(int argc, char * argv[]) usage(); /* parse arguments */ - if (0 > pax_parse_args(argc, &state)) - return -1; + if (EXIT_SUCCESS != pax_parse_args(argc, &state)) + return EXIT_FAILURE; if (state.view) banner(); /* process files */ - if (0 > pax_process_files(&state)) - return -2; - - return 0; + return pax_process_files(&state); } diff -urp paxctl-0.3/paxctl.h paxctl-0.4/paxctl.h --- paxctl-0.3/paxctl.h 2005-05-02 22:21:39.000000000 +0100 +++ paxctl-0.4/paxctl.h 2005-05-29 12:41:03.000000000 +0100 @@ -3,13 +3,13 @@ #include -#define PAXCTL_VERSION "0.3" +#define PAXCTL_VERSION "0.4" struct pax_state; struct elf_ops { void * (* const map_phdr)(const int, const struct pax_state * const); - void (* const modify_phdr)(unsigned char * const, const struct pax_state * const); + int (* const modify_phdr)(unsigned char * const, const struct pax_state * const); union { Elf32_Off _32; Elf64_Off _64; @@ -40,18 +40,18 @@ struct pax_state { #define PT_PAX_FLAGS 0x65041580 -#define PF_PAGEEXEC (1 << 4) /* Enable PAGEEXEC */ -#define PF_NOPAGEEXEC (1 << 5) /* Disable PAGEEXEC */ -#define PF_SEGMEXEC (1 << 6) /* Enable SEGMEXEC */ -#define PF_NOSEGMEXEC (1 << 7) /* Disable SEGMEXEC */ -#define PF_MPROTECT (1 << 8) /* Enable MPROTECT */ -#define PF_NOMPROTECT (1 << 9) /* Disable MPROTECT */ -#define PF_RANDEXEC (1 << 10) /* Enable RANDEXEC */ -#define PF_NORANDEXEC (1 << 11) /* Disable RANDEXEC */ -#define PF_EMUTRAMP (1 << 12) /* Enable EMUTRAMP */ -#define PF_NOEMUTRAMP (1 << 13) /* Disable EMUTRAMP */ -#define PF_RANDMMAP (1 << 14) /* Enable RANDMMAP */ -#define PF_NORANDMMAP (1 << 15) /* Disable RANDMMAP */ +#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */ +#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */ +#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */ +#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */ +#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */ +#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */ +#define PF_RANDEXEC (1U << 10) /* Enable RANDEXEC */ +#define PF_NORANDEXEC (1U << 11) /* Disable RANDEXEC */ +#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */ +#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */ +#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */ +#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */ #endif