aboutsummaryrefslogtreecommitdiff
path: root/misc
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2014-07-30 17:17:25 -0400
committerAnthony G. Basile <blueness@gentoo.org>2014-07-30 17:17:25 -0400
commit774ce372e0a21e58541d34035ed15903b4b5b34a (patch)
treeb9afd5764c222ffff052e7ce8b8e5e5ecf766fac /misc
parentSplit misc/ into misc/ for production and poc/ for experimental stuff. (diff)
downloadelfix-774ce372e0a21e58541d34035ed15903b4b5b34a.tar.gz
elfix-774ce372e0a21e58541d34035ed15903b4b5b34a.tar.bz2
elfix-774ce372e0a21e58541d34035ed15903b4b5b34a.zip
Refactor source tree: separate out fix-gnustack
Diffstat (limited to 'misc')
-rw-r--r--misc/fix-gnustack/ChangeLog46
-rw-r--r--misc/fix-gnustack/Makefile.am6
-rwxr-xr-xmisc/fix-gnustack/autogen.sh9
-rw-r--r--misc/fix-gnustack/configure.ac58
-rw-r--r--misc/fix-gnustack/doc/Makefile.am3
-rw-r--r--misc/fix-gnustack/doc/fix-gnustack.1172
-rw-r--r--misc/fix-gnustack/doc/fix-gnustack.pod54
-rwxr-xr-xmisc/fix-gnustack/doc/make.sh31
-rw-r--r--misc/fix-gnustack/fix-gnustack.c144
-rw-r--r--misc/fix-gnustack/tests/Makefile.am20
-rw-r--r--misc/fix-gnustack/tests/bad-gnustack.c2
-rwxr-xr-xmisc/fix-gnustack/tests/gnustacktest.sh29
12 files changed, 574 insertions, 0 deletions
diff --git a/misc/fix-gnustack/ChangeLog b/misc/fix-gnustack/ChangeLog
new file mode 100644
index 0000000..7e6fc49
--- /dev/null
+++ b/misc/fix-gnustack/ChangeLog
@@ -0,0 +1,46 @@
+2014-07-30
+
+ * Seperate out fix-gnustack. See: https://bugs.gentoo.org/518524
+
+2014-06-07
+
+ * Switch from error() to errx() make the code portable to musl (and BSD).
+
+2013-05-20
+
+ * Add check if ELF_C_RDWR_MMAP is declared in libelf.h. This distinguishes
+ elfutils from libelf. The former will not build on uclibc, but the later
+ does not provide ELF_C_RDWR_MMAP.
+
+2012-07-29
+
+ * remove unnecessary check for yasm in configure.ac
+ * make tests/gnustack machine independant by generating
+ native assembly using gcc
+
+2012-07-27
+
+ * switch from yasm to gcc for assembler for arches other than
+ x86 and amd64
+ * opening an ELF_C_RDWR does not work for either libelf or
+ elfutils, so revert to ELF_C_RDWR_MMAP. This does, however,
+ break linking against libelf
+
+2012-07-24
+
+ * switch from ELF_C_RDWR_MMAP to ELF_C_RDWR to link again libelf
+ for uclibc systems
+
+2011-11-26
+
+ * fix-gnustack and paxctl-ng: fix exit code on success
+
+2011-04-14
+
+ * Initial release of fix-gnustack
+-----
+
+Copyright (C) 2011-2014 Anthony G. Basile
+
+Copying and distribution of this file, with or without modification, are
+permitted provided the copyright notice and this notice are preserved.
diff --git a/misc/fix-gnustack/Makefile.am b/misc/fix-gnustack/Makefile.am
new file mode 100644
index 0000000..821f549
--- /dev/null
+++ b/misc/fix-gnustack/Makefile.am
@@ -0,0 +1,6 @@
+ACLOCAL_AMFLAGS = -I m4
+
+sbin_PROGRAMS = fix-gnustack
+fix_gnustack_SOURCES = fix-gnustack.c
+
+SUBDIRS = doc tests
diff --git a/misc/fix-gnustack/autogen.sh b/misc/fix-gnustack/autogen.sh
new file mode 100755
index 0000000..0b7b16b
--- /dev/null
+++ b/misc/fix-gnustack/autogen.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+aclocal && \
+autoheader && \
+autoconf && \
+automake --add-missing --copy
+
+cd doc
+./make.sh
diff --git a/misc/fix-gnustack/configure.ac b/misc/fix-gnustack/configure.ac
new file mode 100644
index 0000000..2f5a245
--- /dev/null
+++ b/misc/fix-gnustack/configure.ac
@@ -0,0 +1,58 @@
+#
+# configure.ac: this file is part of the elfix package
+# 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/>.
+#
+
+AC_PREREQ([2.69])
+AC_INIT([fix-gnustack], [0.1], [http://bugs.gentoo.org/])
+AC_CONFIG_SRCDIR([fix-gnustack.c])
+AC_CONFIG_HEADERS([config.h])
+AM_INIT_AUTOMAKE([1.12 foreign])
+AM_SILENT_RULES([no])
+
+# Checks for programs.
+AC_PROG_AWK
+AC_PROG_CC
+AC_PROG_SED
+
+# Checks for header files.
+AC_CHECK_HEADERS(
+ [err.h fcntl.h gelf.h libgen.h stdlib.h string.h sys/stat.h sys/types.h unistd.h],
+ [],
+ [AC_MSG_ERROR(["Missing necessary header"])]
+)
+
+# Checks for DECLs.
+AC_CHECK_DECL([ELF_C_RDWR_MMAP],[],[],[[#include <libelf.h>]])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_TYPE_SIZE_T
+
+# Checks for library functions.
+AC_CHECK_LIB(
+ [elf],
+ [elf_begin],
+ [],
+ [AC_MSG_ERROR(["Missing necessary function elf_begin in libelf"])]
+)
+
+AC_CONFIG_FILES([
+ Makefile
+ doc/Makefile
+ tests/Makefile
+])
+
+AC_OUTPUT
diff --git a/misc/fix-gnustack/doc/Makefile.am b/misc/fix-gnustack/doc/Makefile.am
new file mode 100644
index 0000000..b5f33f4
--- /dev/null
+++ b/misc/fix-gnustack/doc/Makefile.am
@@ -0,0 +1,3 @@
+ACLOCAL_AMFLAGS = -I m4
+
+dist_man_MANS = fix-gnustack.1
diff --git a/misc/fix-gnustack/doc/fix-gnustack.1 b/misc/fix-gnustack/doc/fix-gnustack.1
new file mode 100644
index 0000000..06f720a
--- /dev/null
+++ b/misc/fix-gnustack/doc/fix-gnustack.1
@@ -0,0 +1,172 @@
+.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.23)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "FIX-GNUSTACK 1"
+.TH FIX-GNUSTACK 1 "2014-07-30" "fix-gnustack 0.1" "Documentation for fix-gnustack"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+fix\-gnustack \- query or clear any ELF GNU_STACK executable flag
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+\&\fBfix-gnustack\fR \-h
+.PP
+\&\fBfix-gnustack\fR [\-f] \s-1ELF\s0
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fBfix-gnustack\fR scans the program headers of an \s-1ELF\s0 binary or shared
+object library, reports if it has a \s-1GNU_STACK\s0 entry and if it is
+marked both writeable and executable. On PaX hardened kernels where
+memory protection (\s-1MPROTECT\s0) is enforced, execution of binaries with
+\&\s-1GNU_STACKS\s0 marked \s-1WX\s0, or execution of binaries linking against libraries
+with \s-1GNU_STACKS\s0 marked \s-1WX\s0, is terminated by the kernel. When \fBfix-gnustack\fR
+is called without the \fB\-f\fR option on an \s-1ELF\s0, it simply reports the
+\&\s-1RWX\s0 (read/write/execute) flags on any \s-1GNU_STACK\s0 entry found. When called
+with \fB\-f\fR, it clears the X flag if a \s-1GNU_STACK\s0 entry is found and it
+has both W and X flags.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+.IP "\fB\-h\fR" 4
+.IX Item "-h"
+Print out a short help message and exit.
+.IP "[\fB\-f\fR] \s-1ELF\s0" 4
+.IX Item "[-f] ELF"
+\&\*(L"Fix\*(R" the \s-1ELF\s0, ie, remove the X flag from any \s-1GNU_STACK\s0 entry found
+if it has both W and X flags. When called without, it simply reports
+what flags it found.
+.SH "HOMEPAGE"
+.IX Header "HOMEPAGE"
+http://www.gentoo.org/proj/en/hardened/pax\-quickstart.xml
+.SH "REPORTING BUGS"
+.IX Header "REPORTING BUGS"
+Please report bugs at http://bugs.gentoo.org.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fBscanelf\fR(1), \fBdumpelf\fR(1), \fBpaxctl\fR(1), \fBpaxctl-ng\fR(1), \fBpspax\fR(1).
+.SH "AUTHORS"
+.IX Header "AUTHORS"
+\&\fBAnthony G. Basile\fR <blueness@gentoo.org>
diff --git a/misc/fix-gnustack/doc/fix-gnustack.pod b/misc/fix-gnustack/doc/fix-gnustack.pod
new file mode 100644
index 0000000..d94b8b4
--- /dev/null
+++ b/misc/fix-gnustack/doc/fix-gnustack.pod
@@ -0,0 +1,54 @@
+=head1 NAME
+
+B<fix-gnustack> - query or clear any ELF GNU_STACK executable flag
+
+=head1 SYNOPSIS
+
+B<fix-gnustack> -h
+
+B<fix-gnustack> [-f] ELF
+
+=head1 DESCRIPTION
+
+B<fix-gnustack> scans the program headers of an ELF binary or shared
+object library, reports if it has a GNU_STACK entry and if it is
+marked both writeable and executable. On PaX hardened kernels where
+memory protection (MPROTECT) is enforced, execution of binaries with
+GNU_STACKS marked WX, or execution of binaries linking against libraries
+with GNU_STACKS marked WX, is terminated by the kernel. When B<fix-gnustack>
+is called without the B<-f> option on an ELF, it simply reports the
+RWX (read/write/execute) flags on any GNU_STACK entry found. When called
+with B<-f>, it clears the X flag if a GNU_STACK entry is found and it
+has both W and X flags.
+
+=head1 OPTIONS
+
+=over
+
+=item B<-h>
+
+Print out a short help message and exit.
+
+=item [B<-f>] ELF
+
+"Fix" the ELF, ie, remove the X flag from any GNU_STACK entry found
+if it has both W and X flags. When called without, it simply reports
+what flags it found.
+
+=back
+
+=head1 HOMEPAGE
+
+http://www.gentoo.org/proj/en/hardened/pax-quickstart.xml
+
+=head1 REPORTING BUGS
+
+Please report bugs at http://bugs.gentoo.org.
+
+=head1 SEE ALSO
+
+B<scanelf>(1), B<dumpelf>(1), B<paxctl>(1), B<paxctl-ng>(1), B<pspax>(1).
+
+=head1 AUTHORS
+
+B<Anthony G. Basile> <blueness@gentoo.org>
diff --git a/misc/fix-gnustack/doc/make.sh b/misc/fix-gnustack/doc/make.sh
new file mode 100755
index 0000000..f9ed65e
--- /dev/null
+++ b/misc/fix-gnustack/doc/make.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+# make.sh: this file is part of the elfix package
+# 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/>.
+#
+
+# This is run on the developer side with autogen.sh
+
+PKG=$(cat ../configure.ac | grep ^AC_INIT | sed -e 's/^.*(\[//' -e 's/\].*$//')
+VERSION=$(cat ../configure.ac | grep ^AC_INIT | sed -e "s/^.*$PKG\], \[//" -e 's/\].*$//')
+
+pod2man \
+ --official \
+ --section="1" \
+ --release="$PKG $VERSION" \
+ --center="Documentation for fix-gnustack" \
+ --date=$(date +%Y-%m-%d) \
+ fix-gnustack.pod > fix-gnustack.1
diff --git a/misc/fix-gnustack/fix-gnustack.c b/misc/fix-gnustack/fix-gnustack.c
new file mode 100644
index 0000000..59e10be
--- /dev/null
+++ b/misc/fix-gnustack/fix-gnustack.c
@@ -0,0 +1,144 @@
+/*
+ fix-gnustack.c: this file is part of the elfix package
+ 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 <err.h>
+#include <libgen.h>
+
+#include <gelf.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <config.h>
+
+
+void
+print_help(char *v)
+{
+ printf(
+ "Package Name : " PACKAGE_STRING "\n"
+ "Bug Reports : " PACKAGE_BUGREPORT "\n"
+ "Program Name : %s\n"
+ "Description : Check for, or conditionally remove, executable flag from PT_GNU_STACK\n\n"
+ "Usage : %s -f ELF | -h\n"
+ "options : Print out protection flags on PT_GNU_STACK\n"
+ " : -f Remove X if WX flags are set on PT_GNU_STACK\n"
+ " : -h Print out this help\n",
+ basename(v),
+ basename(v)
+ );
+
+ exit(EXIT_SUCCESS);
+}
+
+
+char *
+parse_cmd_args( int c, char *v[], int *flagv )
+{
+ int i, oc;
+
+ if((c != 2)&&(c != 3))
+ errx(EXIT_FAILURE, "Usage: %s -f ELF | -h", v[0]);
+
+ *flagv = 0 ;
+ while((oc = getopt(c, v,":fh")) != -1)
+ switch(oc)
+ {
+ case 'f':
+ *flagv = 1 ;
+ break ;
+ case 'h':
+ print_help(v[0]);
+ break;
+ case '?':
+ default:
+ errx(EXIT_FAILURE, "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_Phdr phdr;
+
+ f_name = parse_cmd_args(argc, argv, &flagv);
+
+ if(elf_version(EV_CURRENT) == EV_NONE)
+ errx(EXIT_FAILURE, "Library out of date.");
+
+ if(flagv)
+ {
+ if((fd = open(f_name, O_RDWR)) < 0)
+ errx(EXIT_FAILURE, "open() fail.");
+ if((elf = elf_begin(fd, ELF_C_RDWR_MMAP, NULL)) == NULL)
+ errx(EXIT_FAILURE, "elf_begin() fail: %s", elf_errmsg(elf_errno()));
+ }
+ else
+ {
+ if((fd = open(f_name, O_RDONLY)) < 0)
+ errx(EXIT_FAILURE, "open() fail.");
+ if((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
+ errx(EXIT_FAILURE, "elf_begin() fail: %s", elf_errmsg(elf_errno()));
+ }
+
+ if(elf_kind(elf) != ELF_K_ELF)
+ errx(EXIT_FAILURE, "elf_kind() fail: this is not an elf file.");
+
+ elf_getphdrnum(elf, &phnum);
+ for(i=0; i<phnum; ++i)
+ {
+ if(gelf_getphdr(elf, i, &phdr) != &phdr)
+ errx(EXIT_FAILURE, "gelf_getphdr(): %s", elf_errmsg(elf_errno()));
+
+ 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: X flag removed\n");
+ phdr.p_flags ^= PF_X;
+ if(!gelf_update_phdr(elf, i, &phdr))
+ errx(EXIT_FAILURE, "gelf_update_phdr(): %s", elf_errmsg(elf_errno()));
+ }
+ }
+ }
+
+ elf_end(elf);
+ close(fd);
+
+ exit(EXIT_SUCCESS);
+}
diff --git a/misc/fix-gnustack/tests/Makefile.am b/misc/fix-gnustack/tests/Makefile.am
new file mode 100644
index 0000000..9db0fd7
--- /dev/null
+++ b/misc/fix-gnustack/tests/Makefile.am
@@ -0,0 +1,20 @@
+ACLOCAL_AMFLAGS = -I m4
+
+noinst_PROGRAMS = bad-gnustack
+
+EXTRA_DIST = gnustacktest.sh
+
+bad-gnustack.s: bad-gnustack.c
+ $(CC) -S $<
+ $(SED) -i -e 's/GNU-stack,"",/GNU-stack,"x",/' $@
+
+bad-gnustack$(EXEEXT): bad-gnustack.s
+ $(CC) -o $@ $<
+
+check_SCRIPTS = gnustacktest
+TEST = $(check_SCRIPTS)
+
+gnustacktest: bad-gnustack
+ $(top_srcdir)/tests/gnustacktest.sh
+
+CLEANFILES = *.o *.s
diff --git a/misc/fix-gnustack/tests/bad-gnustack.c b/misc/fix-gnustack/tests/bad-gnustack.c
new file mode 100644
index 0000000..b6c1f55
--- /dev/null
+++ b/misc/fix-gnustack/tests/bad-gnustack.c
@@ -0,0 +1,2 @@
+// Any c will do here
+int main() { return 0 ; }
diff --git a/misc/fix-gnustack/tests/gnustacktest.sh b/misc/fix-gnustack/tests/gnustacktest.sh
new file mode 100755
index 0000000..f200baf
--- /dev/null
+++ b/misc/fix-gnustack/tests/gnustacktest.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# gnustacktest.sh: this file is part of the elfix package
+# Copyright (C) 2011, 2012 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/>.
+#
+
+before=$(../fix-gnustack -f bad-gnustack)
+before=$(echo ${before} | awk '{ print $2 }')
+after=$(../fix-gnustack bad-gnustack)
+after=$(echo ${after} | awk '{ print $2 }')
+rm bad-gnustack
+if [ "${before}" = "RWX" -a "${after}" = "RW" ]; then
+ exit 0
+else
+ exit 1
+fi