diff options
author | Anthony G. Basile <basile@opensource.dyc.edu> | 2011-04-14 11:45:49 -0400 |
---|---|---|
committer | Anthony G. Basile <basile@opensource.dyc.edu> | 2011-04-14 11:45:49 -0400 |
commit | 5b058e4cb24e0926a0478e8f29f43370cf7d3911 (patch) | |
tree | 1f368cbc534d8aa4ebf4a4d18d35304bd652a6d5 | |
parent | Removed parse-elf.c (diff) | |
download | elfix-5b058e4cb24e0926a0478e8f29f43370cf7d3911.tar.gz elfix-5b058e4cb24e0926a0478e8f29f43370cf7d3911.tar.bz2 elfix-5b058e4cb24e0926a0478e8f29f43370cf7d3911.zip |
Consolidated {fix,get}-gnustack.c
-rw-r--r-- | Makefile.am | 9 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | fix-gnustack.c | 70 | ||||
-rw-r--r-- | get-gnustack.c | 59 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/fix-gnustack.c | 121 | ||||
-rw-r--r-- | tests/Makefile.am | 11 | ||||
-rw-r--r-- | tests/bad.c | 18 | ||||
-rw-r--r-- | tests/good.c | 18 | ||||
-rw-r--r-- | tests/test-bad32.asm | 16 | ||||
-rw-r--r-- | tests/test-bad64.asm | 16 |
11 files changed, 201 insertions, 144 deletions
diff --git a/Makefile.am b/Makefile.am index 1b892a3..a459377 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,8 +1 @@ -SUBDIRS = tests -bin_PROGRAMS = get-gnustack fix-gnustack - -get_gnustack_SOURCES = get-gnustack.c -get_gnustack_LDADD = -lelf - -fix_gnustack_SOURCES = fix-gnustack.c -fix_gnustack_LDADD = -lelf +SUBDIRS = src tests diff --git a/configure.ac b/configure.ac index aac51c5..40e7c47 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.65]) AC_INIT([elf-misc], [0.1], [blueness@gentoo.org]) -AC_CONFIG_SRCDIR([fix-gnustack.c]) +AC_CONFIG_SRCDIR([src/fix-gnustack.c]) #AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([1.11 foreign]) @@ -25,5 +25,7 @@ AC_TYPE_SIZE_T AC_FUNC_ERROR_AT_LINE AC_CONFIG_FILES([Makefile + src/Makefile tests/Makefile]) + AC_OUTPUT diff --git a/fix-gnustack.c b/fix-gnustack.c deleted file mode 100644 index b7e48de..0000000 --- a/fix-gnustack.c +++ /dev/null @@ -1,70 +0,0 @@ - -#include <stdio.h> // printf -#include <stdlib.h> // EXIT_FAILURE -#include <error.h> // error - -#include <gelf.h> // elf_* and gelf_* - -#include <sys/types.h> // open -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> // close - - -int main( int argc, char *argv[]) -{ - int fd; - size_t i, phnum; - - Elf *elf; - GElf_Ehdr ehdr; - GElf_Phdr phdr; - GElf_Word nflags; - - if(elf_version(EV_CURRENT) == EV_NONE) - error(EXIT_FAILURE, 0, "Library out of date."); - - if(argc != 2) - error(EXIT_FAILURE, 0, "Usage: %s <filename>", argv[0]); - - if((fd = open(argv[1], O_RDWR)) < 0) - error(EXIT_FAILURE, 0, "open() fail."); - - if((elf = elf_begin(fd, ELF_C_RDWR_MMAP, NULL)) == NULL) - error(EXIT_FAILURE, 0, "elf_begin() fail: %s", elf_errmsg(-1)); - - if(elf_kind(elf) != ELF_K_ELF) - error(EXIT_FAILURE, 0, "elf_kind() report: this is not an elf file."); - - if(gelf_getehdr(elf,&ehdr) == NULL) - error(EXIT_FAILURE, 0, "gelf_getehdr() fail: %s", elf_errmsg(-1)); - - elf_getphdrnum(elf, &phnum); - for(i=0; i<phnum; ++i) - { - if(gelf_getphdr(elf, i, &phdr) != &phdr) - error(EXIT_FAILURE, 0, "gelf_getphdr(): %s", elf_errmsg(-1)); - - if(phdr.p_type == PT_GNU_STACK) - { - printf("GNU_STACK: "); - if( phdr.p_flags & PF_R ) printf("R"); - if( phdr.p_flags & PF_W ) printf("W"); - if( phdr.p_flags & PF_X ) printf("X"); - printf("\n"); - - if((phdr.p_flags & PF_W) && (phdr.p_flags & PF_X)) - { - printf("W&X found, flipping X flag ...\n"); - nflags = phdr.p_flags ^ PF_X; - printf("oflags=%u PF_X=%d nflags=%u\n", phdr.p_flags, PF_X, nflags); - - phdr.p_flags = nflags ; - gelf_update_phdr(elf, i, &phdr); - } - } - } - - elf_end(elf); - close(fd); -} diff --git a/get-gnustack.c b/get-gnustack.c deleted file mode 100644 index 2cbab2f..0000000 --- a/get-gnustack.c +++ /dev/null @@ -1,59 +0,0 @@ - -#include <stdio.h> // printf -#include <stdlib.h> // EXIT_FAILURE -#include <error.h> // error - -#include <gelf.h> // elf_* and gelf_* - -#include <sys/types.h> // open -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> // close - - -int main( int argc, char *argv[]) -{ - int fd; - size_t i, phnum; - - Elf *elf; - GElf_Ehdr ehdr; - GElf_Phdr phdr; - - if(elf_version(EV_CURRENT) == EV_NONE) - error(EXIT_FAILURE, 0, "Library out of date."); - - if(argc != 2) - error(EXIT_FAILURE, 0, "Usage: %s <filename>", argv[0]); - - if((fd = open(argv[1], O_RDONLY)) == -1) - error(EXIT_FAILURE, 0, "open() fail."); - - if((elf = elf_begin(fd, ELF_C_READ, (Elf *)0)) == NULL) - error(EXIT_FAILURE, 0, "elf_begin() fail: %s", elf_errmsg(-1)); - - if(elf_kind(elf) != ELF_K_ELF) - error(EXIT_FAILURE, 0, "elf_kind() report: this is not an elf file."); - - if(gelf_getehdr(elf,&ehdr) == NULL) - error(EXIT_FAILURE, 0, "gelf_getehdr() fail: %s", elf_errmsg(-1)); - - elf_getphdrnum(elf, &phnum); - for (i=0; i<phnum; ++i) - { - if(gelf_getphdr(elf, i, &phdr) != &phdr) - error(EXIT_FAILURE, 0, "gelf_getphdr(): %s", elf_errmsg(-1)); - - if(phdr.p_type == PT_GNU_STACK) - { - printf("GNU_STACK: "); - if( phdr.p_flags & PF_R ) printf("R"); - if( phdr.p_flags & PF_W ) printf("W"); - if( phdr.p_flags & PF_X ) printf("X"); - printf("\n"); - } - } - - elf_end(elf); - close(fd); -} diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..e63a5f2 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,3 @@ +bin_PROGRAMS = fix-gnustack +fix_gnustack_SOURCES = fix-gnustack.c +fix_gnustack_LDADD = -lelf diff --git a/src/fix-gnustack.c b/src/fix-gnustack.c new file mode 100644 index 0000000..00a0c02 --- /dev/null +++ b/src/fix-gnustack.c @@ -0,0 +1,121 @@ +/* + fix-gnustack.c: check and optionally remove exec flag on Elf GNU_STACK + Copyright (C) 2011 Anthony G. Basile + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <error.h> + +#include <gelf.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + + + +char * +parse_cmd_args( int c, char *v[], int *flagv ) +{ + int i, oc; + + if((c != 2)&&(c != 3)) + error(EXIT_FAILURE, 0, "Usage: %s [-f] elffile", v[0]); + + *flagv = 0 ; + while((oc = getopt(c, v,":f")) != -1) + switch(oc) + { + case 'f': + *flagv = 1 ; + break ; + case '?': + default: + error(EXIT_FAILURE, 0, "option -%c is invalid: ignored.", optopt ) ; + } + + return v[optind] ; +} + + + +int +main( int argc, char *argv[]) +{ + int fd, flagv; + char *f_name; + size_t i, phnum; + + Elf *elf; + GElf_Ehdr ehdr; + GElf_Phdr phdr; + + f_name = parse_cmd_args( argc, argv, &flagv ); + + if(elf_version(EV_CURRENT) == EV_NONE) + error(EXIT_FAILURE, 0, "Library out of date."); + + if(flagv) + { + if((fd = open(f_name, O_RDWR)) < 0) + error(EXIT_FAILURE, 0, "open() fail."); + if((elf = elf_begin(fd, ELF_C_RDWR_MMAP, NULL)) == NULL) + error(EXIT_FAILURE, 0, "elf_begin() fail: %s", elf_errmsg(-1)); + } + else + { + if((fd = open(f_name, O_RDONLY)) < 0) + error(EXIT_FAILURE, 0, "open() fail."); + if((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) + error(EXIT_FAILURE, 0, "elf_begin() fail: %s", elf_errmsg(-1)); + } + + if(elf_kind(elf) != ELF_K_ELF) + error(EXIT_FAILURE, 0, "elf_kind() fail: this is not an elf file."); + + if(gelf_getehdr(elf,&ehdr) == NULL) + error(EXIT_FAILURE, 0, "gelf_getehdr() fail: %s", elf_errmsg(-1)); + + elf_getphdrnum(elf, &phnum); + for(i=0; i<phnum; ++i) + { + if(gelf_getphdr(elf, i, &phdr) != &phdr) + error(EXIT_FAILURE, 0, "gelf_getphdr(): %s", elf_errmsg(-1)); + + if(phdr.p_type == PT_GNU_STACK) + { + printf("GNU_STACK: "); + if( phdr.p_flags & PF_R ) printf("R"); + if( phdr.p_flags & PF_W ) printf("W"); + if( phdr.p_flags & PF_X ) printf("X"); + printf("\n"); + + if(flagv && (phdr.p_flags & PF_W) && (phdr.p_flags & PF_X)) + { + printf("W&X FOUND: flipping X flag ...\n"); + phdr.p_flags ^= PF_X; + if(!gelf_update_phdr(elf, i, &phdr)) + error(EXIT_FAILURE, 0, "gelf_update_phdr(): %s", elf_errmsg(-1)); + } + } + } + + elf_end(elf); + close(fd); +} diff --git a/tests/Makefile.am b/tests/Makefile.am index 1ac6e14..6ac6da6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -17,14 +17,17 @@ test.sh: @echo "================================================================================" @echo @echo "Good Elf" - @../get-gnustack good + @../src/fix-gnustack good @echo @echo "Bad Elf" - @../get-gnustack bad + @../src/fix-gnustack bad @echo @echo "Fixing Bad Elf" - @../fix-gnustack bad - @../get-gnustack bad + @../src/fix-gnustack -f bad + @echo + @echo "Fixed Bad Elf" + @../src/fix-gnustack bad + @rm -f good bad @echo @echo "================================================================================" diff --git a/tests/bad.c b/tests/bad.c index 7999e35..74105ed 100644 --- a/tests/bad.c +++ b/tests/bad.c @@ -1,7 +1,21 @@ +/* + bad.c: C source for sample elf with X on GNU_STACK + Copyright (C) 2011 Anthony G. Basile -#include <stdlib.h> + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -//extern int badness(); + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +#include <stdlib.h> int main() { diff --git a/tests/good.c b/tests/good.c index 196d2fc..ff7700e 100644 --- a/tests/good.c +++ b/tests/good.c @@ -1,3 +1,21 @@ +/* + good.c: C source for sample elf with no X on GNU_STACK + Copyright (C) 2011 Anthony G. Basile + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + int main() { ; diff --git a/tests/test-bad32.asm b/tests/test-bad32.asm index 1bf8607..df8296c 100644 --- a/tests/test-bad32.asm +++ b/tests/test-bad32.asm @@ -1,3 +1,19 @@ +;test-bad32.asm: 32-bit asm source for sample elf with X on GNU_STACK +;Copyright (C) 2011 Anthony G. Basile +; +;This program is free software: you can redistribute it and/or modify +;it under the terms of the GNU General Public License as published by +;the Free Software Foundation, either version 3 of the License, or +;(at your option) any later version. +; +;This program is distributed in the hope that it will be useful, +;but WITHOUT ANY WARRANTY; without even the implied warranty of +;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;GNU General Public License for more details. +; +;You should have received a copy of the GNU General Public License +;along with this program. If not, see <http://www.gnu.org/licenses/>. + global badness SECTION .text diff --git a/tests/test-bad64.asm b/tests/test-bad64.asm index e01531d..3a8af73 100644 --- a/tests/test-bad64.asm +++ b/tests/test-bad64.asm @@ -1,3 +1,19 @@ +;test-bad64.asm: 64-bit asm source for sample elf with X on GNU_STACK +;Copyright (C) 2011 Anthony G. Basile +; +;This program is free software: you can redistribute it and/or modify +;it under the terms of the GNU General Public License as published by +;the Free Software Foundation, either version 3 of the License, or +;(at your option) any later version. +; +;This program is distributed in the hope that it will be useful, +;but WITHOUT ANY WARRANTY; without even the implied warranty of +;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;GNU General Public License for more details. +; +;You should have received a copy of the GNU General Public License +;along with this program. If not, see <http://www.gnu.org/licenses/>. + global badness SECTION .text |