This is an automated email from the git hooks/post-receive script. jforbes pushed a commit to branch master in repository kernel-tests. commit 6e3d89c02437a6cc5cef0fdc6bad578e700cf4b8 Author: Dave Jones <davej@xxxxxxxxxx> Date: Tue Jun 12 11:59:51 2012 -0400 Add paxtest --- .gitignore | 1 + default/paxtest/.gitignore | 41 ++++ default/paxtest/COPYING | 340 +++++++++++++++++++++++++++++ default/paxtest/ChangeLog | 1 + default/paxtest/Makefile | 24 ++ default/paxtest/Makefile.OpenBSD | 172 +++++++++++++++ default/paxtest/Makefile.psm | 214 ++++++++++++++++++ default/paxtest/README | 210 ++++++++++++++++++ default/paxtest/anonmap.c | 42 ++++ default/paxtest/body.c | 109 +++++++++ default/paxtest/body.h | 4 + default/paxtest/chpax-0.7/Changelog | 21 ++ default/paxtest/chpax-0.7/Makefile | 33 +++ default/paxtest/chpax-0.7/README | 11 + default/paxtest/chpax-0.7/aout.c | 18 ++ default/paxtest/chpax-0.7/chpax.1 | 80 +++++++ default/paxtest/chpax-0.7/chpax.c | 97 ++++++++ default/paxtest/chpax-0.7/chpax.h | 77 +++++++ default/paxtest/chpax-0.7/elf32.c | 22 ++ default/paxtest/chpax-0.7/elf64.c | 22 ++ default/paxtest/chpax-0.7/flags.c | 147 +++++++++++++ default/paxtest/chpax-0.7/io.c | 118 ++++++++++ default/paxtest/crt1S.S | 57 +++++ default/paxtest/debian/changelog | 75 +++++++ default/paxtest/debian/control | 24 ++ default/paxtest/debian/copyright | 8 + default/paxtest/debian/dirs | 2 + default/paxtest/debian/docs | 5 + default/paxtest/debian/manpage.1.ex | 60 +++++ default/paxtest/debian/manpage.sgml.ex | 152 +++++++++++++ default/paxtest/debian/paxtest.sgml | 167 ++++++++++++++ default/paxtest/debian/rules | 104 +++++++++ default/paxtest/execbss.c | 31 +++ default/paxtest/execdata.c | 31 +++ default/paxtest/execheap.c | 36 +++ default/paxtest/execstack.c | 30 +++ default/paxtest/genpaxtest | 74 +++++++ default/paxtest/getamap.c | 30 +++ default/paxtest/getheap.c | 24 ++ default/paxtest/getmain.c | 19 ++ default/paxtest/getshlib.c | 36 +++ default/paxtest/getstack.c | 18 ++ default/paxtest/interp.c | 5 + default/paxtest/mprotanon.c | 65 ++++++ default/paxtest/mprotbss.c | 39 ++++ default/paxtest/mprotdata.c | 39 ++++ default/paxtest/mprotheap.c | 44 ++++ default/paxtest/mprotshbss.c | 71 ++++++ default/paxtest/mprotshdata.c | 71 ++++++ default/paxtest/mprotstack.c | 35 +++ default/paxtest/randamap.c | 12 + default/paxtest/randbody.c | 63 ++++++ default/paxtest/randheap1.c | 12 + default/paxtest/randheap2.c | 12 + default/paxtest/randmain1.c | 12 + default/paxtest/randmain2.c | 12 + default/paxtest/randshlib.c | 12 + default/paxtest/randstack1.c | 12 + default/paxtest/randstack2.c | 12 + default/paxtest/results/Adamantix.blackhat | 33 +++ default/paxtest/results/Adamantix.kiddie | 33 +++ default/paxtest/results/Gentoo.blackhat | 33 +++ default/paxtest/results/Results.README | 10 + default/paxtest/rettofunc1.c | 31 +++ default/paxtest/rettofunc1x.c | 31 +++ default/paxtest/rettofunc2.c | 25 +++ default/paxtest/rettofunc2x.c | 25 +++ default/paxtest/runtest.sh | 20 ++ default/paxtest/shellcode.h | 37 ++++ default/paxtest/shlibbss.c | 63 ++++++ default/paxtest/shlibdata.c | 63 ++++++ default/paxtest/shlibtest.c | 16 ++ default/paxtest/shlibtest2.c | 17 ++ default/paxtest/targets | 10 + default/paxtest/writetext.c | 56 +++++ 75 files changed, 3818 insertions(+) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.o diff --git a/default/paxtest/.gitignore b/default/paxtest/.gitignore new file mode 100644 index 0000000..db10415 --- /dev/null +++ b/default/paxtest/.gitignore @@ -0,0 +1,41 @@ +anonmap +chpax +execbss +execdata +execheap +execstack +getamap +getheap1 +getheap2 +getmain1 +getmain2 +getshlib +getstack1 +getstack2 +mprotanon +mprotbss +mprotdata +mprotheap +mprotshbss +mprotshdata +mprotstack +paxbin +paxtest +paxtest.log +randamap +randheap1 +randheap2 +randmain1 +randmain2 +randshlib +randstack1 +randstack2 +rettofunc1 +rettofunc1x +rettofunc2 +rettofunc2x +shlibbss +shlibdata +shlibtest.so +shlibtest2.so +writetext diff --git a/default/paxtest/COPYING b/default/paxtest/COPYING new file mode 100644 index 0000000..60549be --- /dev/null +++ b/default/paxtest/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/default/paxtest/ChangeLog b/default/paxtest/ChangeLog new file mode 120000 index 0000000..d526672 --- /dev/null +++ b/default/paxtest/ChangeLog @@ -0,0 +1 @@ +debian/changelog \ No newline at end of file diff --git a/default/paxtest/Makefile b/default/paxtest/Makefile new file mode 100644 index 0000000..e38ae7e --- /dev/null +++ b/default/paxtest/Makefile @@ -0,0 +1,24 @@ +#!/usr/bin/make +# +# PaXtest master makefile +# Copyright(c) 2003 by Peter Busser <peter@xxxxxxxxxxxxx> +# This file has been released under the GNU Public Licence version 2 or later + +all: + @cat targets + +linux: + make -f Makefile.psm + +linux32: + make -f Makefile.psm THEARCH=-m32 + +linux64: + make -f Makefile.psm THEARCH=-m64 + +openbsd: + gmake -f Makefile.OpenBSD + +clean: + make -f Makefile.psm clean + diff --git a/default/paxtest/Makefile.OpenBSD b/default/paxtest/Makefile.OpenBSD new file mode 100644 index 0000000..b155313 --- /dev/null +++ b/default/paxtest/Makefile.OpenBSD @@ -0,0 +1,172 @@ +#!/usr/bin/gmake + +CC=gcc +CFLAGS= +LDFLAGS= +ifndef RUNDIR +RUNDIR=. +endif + +CFLAGS+=-DRUNDIR=\"${RUNDIR}\" -fno-stack-protector -ftrampolines +LDFLAGS+=-lpthread + + +TESTS= anonmap \ + execbss \ + execdata \ + execheap \ + execstack \ + mprotanon \ + mprotbss \ + mprotdata \ + mprotheap \ + mprotshbss \ + mprotshdata \ + mprotstack \ + randamap \ + randheap1 \ + randmain1 \ + randshlib \ + randstack1 \ + randstack2 \ + rettofunc1 \ + rettofunc1x \ + rettofunc2 \ + rettofunc2x \ + shlibbss \ + shlibdata \ + writetext + +UTILS= getamap \ + getheap1 \ + getheap2 \ + getmain1 \ + getmain2 \ + getshlib \ + getstack1 \ + getstack2 + +SHLIBS= shlibtest.so \ + shlibtest2.so + +all: $(SHLIBS) $(TESTS) $(UTILS) paxtest + +clean: + -rm -f *.o *.s *~ core + -rm -f $(SHLIBS) $(TESTS) $(UTILS) + -rm -f paxtest paxtest.log a.out + +ifdef DESTDIR +ifdef BINDIR +ifdef RUNDIR +install: all + mkdir -p $(DESTDIR)/$(RUNDIR) + cp $(SHLIBS) $(TESTS) $(UTILS) $(DESTDIR)/$(RUNDIR) + mkdir -p $(DESTDIR)/$(BINDIR) + cp paxtest $(DESTDIR)/$(BINDIR) + chmod 755 $(DESTDIR)/$(BINDIR)/paxtest +endif +endif +endif + +paxtest: $(TESTS) genpaxtest + sh genpaxtest $(TESTS) + +anonmap: body.o anonmap.o + +execbss: body.o execbss.o + +execdata: body.o execdata.o + +execheap: body.o execheap.o + +execstack: body.o execstack.o + +getheap1: getheap.o + $(CC) $(LDFLAGS) -o $@ $+ + +getheap2: getheap.o + $(CC) -shared -o $@ $+ + +getheap.o: getheap.c + $(CC) $(CFLAGS) -fPIC -o $@ -c $< + +getamap.o: getamap.c + +getmain1: getmain.o + $(CC) $(LDFLAGS) -o $@ $+ + +getmain2: getmain2.o + $(CC) -shared -o $@ $+ + +getmain2.o: getmain.c + $(CC) $(CFLAGS) -fPIC -o $@ -c $< + +getshlib: getshlib.o + +getstack1: getstack.o + $(CC) $(LDFLAGS) -o $@ $+ + +getstack2: getstack1 + rm -f $@ + cp getstack1 $@ + chmod +x $@ + +mprotanon: body.o mprotanon.o + +mprotbss: body.o mprotbss.o + +mprotheap: body.o mprotheap.o + +mprotdata: body.o mprotdata.o + +mprotshbss: body.o mprotshbss.o shlibtest.so + +mprotshdata: body.o mprotshdata.o shlibtest.so + +mprotstack: body.o mprotstack.o + +randamap: randbody.o randamap.o + +randheap1: randbody.o randheap1.o + +randheap2: randbody.o randheap2.o + +randmain1: randbody.o randmain1.o + +randmain2: randbody.o randmain2.o + +randshlib: randbody.o randshlib.o + +randstack1: randbody.o randstack1.o + +randstack2: randbody.o randstack2.o + +rettofunc1: body.o rettofunc1.o + +rettofunc1x: body.o rettofunc1x.o + $(CC) $(LDFLAGS) -o $@ $+ + +rettofunc2: body.o rettofunc2.o + +rettofunc2x: body.o rettofunc2x.o + $(CC) $(LDFLAGS) -o $@ $+ + +shlibtest.o: shlibtest.c + $(CC) $(CFLAGS) -fPIC -c $< -o $@ + +shlibtest2.o: shlibtest2.c + $(CC) $(CFLAGS) -fPIC -c $< -o $@ + +shlibtest.so: shlibtest.o + $(CC) $(SHLDFLAGS) -shared -o $@ $+ + +shlibtest2.so: shlibtest2.o + $(CC) $(SHLDFLAGS) -shared -o $@ $+ + +shlibbss: body.o shlibbss.o shlibtest.so shlibtest2.so + +shlibdata: body.o shlibdata.o shlibtest.so shlibtest2.so + +writetext: body.o writetext.o shlibtest.so + diff --git a/default/paxtest/Makefile.psm b/default/paxtest/Makefile.psm new file mode 100644 index 0000000..68b960f --- /dev/null +++ b/default/paxtest/Makefile.psm @@ -0,0 +1,214 @@ +#!/usr/bin/make + +# tested with make-3.79.1/gcc-2.96 (shared) and make-3.80/gcc-3.3.2/3 (pie) +# make-3.79.1 does not support $$@ as target requirement (works for make-3.80) + +# preliminaries: +# Gentoo modifies the specs adding pie/nopie to enable/disable ET_DYN binaries + +CC := gcc +LD := ld +CC_PIC := -fPIC + +check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; \ + then echo "$(1)"; else echo "$(2)"; fi) + +check_as = $(shell if $(CC) -Wa,$(1) -Wa,-Z -c -o /dev/null -xassembler /dev/null > /dev/null 2>&1; \ + then echo "-Wa,$(1)"; fi) + +# stack protector has to be disabled for some tests +CC_SSP := $(call check_gcc,-fno-stack-protector,) +CC_SSP += $(call check_gcc,-fno-stack-protector-all,) + +ASFLAGS := $(call check_as,--noexecstack) + +CC_PIE := $(call check_gcc,-fPIE,-fPIC) + +CC_TRAMPOLINES := $(call check_gcc,-ftrampolines,) + +CC_MSECURE_PLT := $(call check_gcc,-msecure-plt,) + +LD_PIE = $(shell $(LD) --help | grep -q pie && echo "-pie") +ifneq ($(LD_PIE),) +# Gentoo (hardened specs enabled) +CC_ETEXEC = $(shell $(CC) -dumpspecs | grep -q "\!nopie" && echo "-nopie") +LD_ETEXEC = $(CC_ETEXEC) +endif + +ifeq ($(LD_PIE),) +LD_PIE = -shared +endif + +# check for installed binaries +CHPAXBIN := $(shell if which chpax >/dev/null 2>&1 ; then echo chpax; fi) +PAXCTLBIN := $(shell if which paxctl >/dev/null 2>&1 ; then echo paxctl; fi) +# should somehow use this to see if we really need paxctl +# list=`paxctl -qQv /sbin/paxctl 2>/dev/null`; if echo $list | grep -q "PaX flags" ; then echo paxctl; fi +# instead we use both markings to have paxtest running correctly on all platforms + +ifneq ($(PAXCTLBIN),) +DUMMY := $(shell echo '${PAXCTLBIN} $$*' > paxbin) +endif + +# for some reason the .c files need it, else GNU_STACK=RWE +OPT_FLAGS := -O2 $(ASFLAGS) +PTHREAD := -lpthread +# define stripping of binaries/libs here, or set these on make's commandline, +# else you'll loose the chpax flags! +LDFLAGS := +SHLDFLAGS := +ifndef RUNDIR +RUNDIR := . +endif + +# The Hardened GCC compiler has stack protector on by default, this +# could interfere with the results of this test. + +CFLAGS := $(OPT_FLAGS) -D_FORTIFY_SOURCE=0 -DRUNDIR=\"${RUNDIR}\" $(CC_SSP) $(CC_TRAMPOLINES) + +ifneq ($(THEARCH),) +CFLAGS += $(THEARCH) +LDFLAGS += $(THEARCH) +SHLDFLAGS += $(THEARCH) +endif + +EXEC_TESTS = anonmap execbss execdata execheap execstack +MPROT_TESTS = mprotanon mprotbss mprotdata mprotheap mprotstack +SHLIB_TESTS = shlibbss shlibdata +MPROTSH_TESTS = mprotshbss mprotshdata writetext +RAND_TESTS = randamap randheap1 randheap2 randmain1 randmain2 randshlib randstack1 randstack2 +RET_TESTS = rettofunc1 rettofunc2 +RETX_TESTS = rettofunc1x rettofunc2x + +TESTS = $(EXEC_TESTS) $(SHLIB_TESTS) $(MPROT_TESTS) $(MPROTSH_TESTS) $(RAND_TESTS) $(RET_TESTS) $(RETX_TESTS) + +UTILS= getamap getheap1 getheap2 getmain1 getmain2 getshlib getstack1 getstack2 + +SHLIBS= shlibtest.so shlibtest2.so + +ifeq ($(CHPAXBIN),) +CHPAXVER := 0.7 +CHPAX := chpax-$(CHPAXVER) +CHPAXSRC := $(CHPAX)/aout.c $(CHPAX)/chpax.c $(CHPAX)/elf32.c $(CHPAX)/elf64.c $(CHPAX)/flags.c $(CHPAX)/io.c +CHPAXBIN := ./chpax +all: chpax $(SHLIBS) $(TESTS) $(UTILS) paxtest +else +all: $(SHLIBS) $(TESTS) $(UTILS) paxtest +endif + +# we need the failure handling, for kernels not supporting EI_PAX +DUMMY := $(shell echo '${CHPAXBIN} $$* >/dev/null 2>/dev/null ||:' >> paxbin; chmod +x paxbin) + +PAXBIN := ./paxbin +DL := -ldl + +clean: + -rm -f *.o *.s *~ core + -rm -f $(TESTS) $(UTILS) $(SHLIBS) + -rm -f paxtest paxtest.log a.out dumpspecs paxbin + -rm -f chpax-0.7/*.o + -rm -f chpax + +ifdef DESTDIR +ifdef BINDIR +ifdef RUNDIR +install: all + mkdir -p $(DESTDIR)/$(RUNDIR) + cp $(SHLIBS) $(TESTS) $(UTILS) $(DESTDIR)/$(RUNDIR) + mkdir -p $(DESTDIR)/$(BINDIR) + cp paxtest $(DESTDIR)/$(BINDIR) + chmod 755 $(DESTDIR)/$(BINDIR)/paxtest +endif +endif +endif + +chpax: $(CHPAXSRC:.c=.o) + $(CC) $(LDFLAGS) -o $@ $^ + +paxtest: $(TESTS) genpaxtest + sh genpaxtest $(TESTS) + +.S.o: + $(CC) $(CFLAGS) $(CC_PIE) $(ASFLAGS) -o $@ -c $< +.c.o: + $(CC) $(CFLAGS) -o $@ -c $< + +$(EXEC_TESTS) $(MPROT_TESTS): body.o + $(CC) $(CFLAGS) -o $@.o -c $@.c + $(CC) $(LDFLAGS) $(PTHREAD) -o $@ $< $@.o + +$(RAND_TESTS): randbody.o + $(CC) $(CFLAGS) -o $@.o -c $@.c + $(CC) $(LDFLAGS) -o $@ $< $@.o + +getamap: getamap.o + $(CC) $(LDFLAGS) -o $@ $@.o + +# get heap1/main1 are built w/o PIC +get%1.o: get%.c + $(CC) $(CFLAGS) $(CC_ETEXEC) -o $@ -c $< + +# get heap2/main2 are built w/ PIC +get%2.o: get%.c + $(CC) $(CFLAGS) $(CC_PIE) -o $@ -c $< + +# Adamantix uses the PIC version (getheap2.o), not necessary for ET_EXEC +# build as ET_EXEC (not in Adamantix's Makefile) +getheap1: getheap1.o + $(CC) $(LDFLAGS) $(LD_ETEXEC) -o $@ $< + +getmain1: getmain1.o + $(CC) $(LDFLAGS) $(LD_ETEXEC) -o $@ $< + -$(PAXBIN) -C $@ + $(PAXBIN) -SPRXM $@ + +getheap2 getmain2: getheap2.o getmain2.o + $(CC) $(LDFLAGS) $(LD_PIE) -o $@ $@.o || (echo -e "#!/bin/sh\necho $@ pie not implemented" > $@; chmod +x $@) + +getshlib: getshlib.o + $(CC) $(LDFLAGS) -o $@ $< $(DL) + +# ET_EXEC and usage of "m" is not confirmed (as in Gentoo patch) +# Adamantix does not use it +# Pax Team does not want "m" for getstack1/2 +getstack1: getstack.o + $(CC) $(LDFLAGS) -o $@ $< + -$(PAXBIN) -C $@ + $(PAXBIN) -SRpm $@ + +getstack2: getstack.o + $(CC) $(LDFLAGS) -o $@ $< + # disable segmexec, kernel else overrides pageexec + -$(PAXBIN) -C $@ + $(PAXBIN) -PRsm $@ + +$(MPROTSH_TESTS): body.o shlibtest.so + $(CC) $(CFLAGS) -o $@.o -c $@.c + $(CC) $(LDFLAGS) $(DL) $(PTHREAD) -o $@ $@.o $^ + +# used for RANDEXEC'd binaries +retbody.o: body.c + $(CC) $(CFLAGS) $(CC_ETEXEC) -o $@ -c $< + +# build as ET_EXEC (recommended by PaX Team, not really a requirement) +$(RET_TESTS): retbody.o + $(CC) $(CFLAGS) $(CC_ETEXEC) -o $@.o -c $@.c + $(CC) $(LDFLAGS) $(LD_ETEXEC) $(PTHREAD) -o $@ $< $@.o + +# build as ET_EXEC (not in Adamantix's Makefile) +$(RETX_TESTS): retbody.o + $(CC) $(CFLAGS) $(CC_ETEXEC) -o $@.o -c $@.c + $(CC) $(LDFLAGS) $(LD_ETEXEC) $(PTHREAD) -o $@ $< $@.o + -$(PAXBIN) -C $@ + $(PAXBIN) -SPXM $@ + +# should also shlibbss.o and shlibdata.o be built w/ PIC? +# if yes, remove tes from target and dependency +shlibtes%.o: shlibtes%.c + $(CC) $(CFLAGS) $(CC_PIC) -o $@ -c $< + +shlib%.so: shlib%.o + $(CC) $(SHLDFLAGS) -shared -o $@ $< + +$(SHLIB_TESTS): body.o $(SHLIBS) shlibbss.o shlibdata.o + $(CC) $(LDFLAGS) $(PTHREAD) -o $@ body.o $@.o $(SHLIBS) $(DL) diff --git a/default/paxtest/README b/default/paxtest/README new file mode 100644 index 0000000..15ab406 --- /dev/null +++ b/default/paxtest/README @@ -0,0 +1,210 @@ +Paxtest v0.9.9 README file + +Copyright (c)2004 by Peter Busser <peter@xxxxxxxxxxxxx> + +Additional architecture/target support & fixes +by Brad Spengler <spender@xxxxxxxxxxxxxx> + +This file has been released under the GNU GPL version 2 or later. + + +History: +------- +When I started the Adamantix project, one of the first things I did was to add +PaX functionality to the kernel. PaX is a process memory protection patch. +Anything that happens outside the kernel on a UNIX system happens inside a +process. There are many attacks on the Internet that try to corrupt the process +memory, in order to make it do something for which it was not intended. One +example of such an attack is the so called buffer overflow attack. This kind of +attack is one of the most popular at this moment. + +PaX protects against such attacks. Or so the author claims. When I started to +add PaX to Adamantix, almost nothing happened. A few libraries broke, but that +was easy to fix, and that was it. I expected many programs to break. So I +started to wonder: ``Does this patch really do anything?'' Instead of +speculating, I decided to write a test suite. After some time, the first +version of paxtest was ready. More functionality was added. With the addition +of every test, it proved that PaX was working just fine. I decided to publish +paxtest, because it can be useful for other people to test the functionality +of the memory protection of their system(s). + + +Compiling paxtest: +----------------- +Compiling paxtest should be quite straightforward. First unpack paxtest. Then +cd into the directory. And then run one of the following: + +make linux (to create Linux binaries) +make openbsd (to create OpenBSD binaries) + +(Type make to get the above list.) + + +Running paxtest: +--------------- +In order to run paxtest, type the following: + +./paxtest kiddie (to run paxtest in script kiddie mode) + +or + +./paxtest blackhat (to run paxtest in blackhat mode) + +This will create a file paxtest.log in the current directory. + + +Kiddie and blackhat mode: +------------------------ +Paxtest provides two modes. The first mode is the so called kiddie mode, which +makes paxtest behave rather nicely. This simulates the level of sophistication +displayed by script kiddies. Good results in this mode do not necessarily mean +that the security level of your system is high. + +The second mode, the blackhat mode, makes paxtest use of a few tricks to try +to get around the protection of the kernel. The attacks done by paxtest in this +mode can be performed in real life by attackers too. But the level of +sophistication is somewhat higher than those of the kiddie mode and the chance +of success is somewhat lower. But there is still a realistic chance of success. + +People who are concerned about the security of their systems should look at +the blackhat mode results. + + +The tests: +--------- +There are two types of tests in paxtest. First there are tests which try +different ways to write and then run exploit code. The more different exploits +are stopped, the better the protection provided by the system. Note that the +tests simulate what an exploit could (and would) do, not what an application +does normally. This is especially important in the mprotect tests because +some people claim that normal applicatons do not do this - indeed, but that +is not what these tests are about, they simulate exploits, not applications. + +Second, there is a number of tests that measure the randomisation of the +system. Randomisation does not provide any security, but only makes it harder +for the attacker to guess where to attack (it is in fact security through +obscurity). It is like rearranging the furniture in a pitch dark room every +time someone enters. The more random the furniture is placed, the more likely +it is that someone stumbles over it. The same applies to randomisation in this +context, randomisation makes it more likely that an attack does not succeed. +In short: More random bits is better. Zero bits means: No randomisation. + + +Executable anonymous mapping +Executable bss +Executable data +Executable heap +Executable stack + + These tests try to write data to memory and then try to execute it as + if it was executable code. This is exactly what most buffer exploits + do. There are five tests, each test tests one specific memory area. + +Executable anonymous mapping (mprotect) +Executable bss (mprotect) +Executable data (mprotect) +Executable heap (mprotect) +Executable stack (mprotect) + + These tests do the same as the previous tests. But now the test also + tries to disable the memory protection in the kernel using mprotect(). + It changes the protection status of memory. An attacker can use it to + try to switch off memory protection and execute shellcode as usual. + +Executable shared library bss (mprotect) +Executable shared library data (mprotect) + + These tests try to overwrite two different data areas in a shared + library. After that, it tries to execute the data as if it was code. + Again, these tests try to switch off the memory protection using + mprotect(). + +Anonymous mapping randomisation test + + Anonymous mappings are used for dynamically allocating memory in a + program. This test tries to figure out the number of random bits used + when such an anonymous mapping is requested. More bits is better. + +Heap randomisation test (ET_EXEC) +Heap randomisation test (ET_DYN) + + The heap is used for allocating small chunks of memory in a program. + There there are two different types of executables, ET_EXEC (normal + executables) and ET_DYN (basically executable shared libraries). The + randomisation can depend on the kind of executable, therefore there + are two tests. + + Most Linux distributions ship with ET_EXEC executables only. So for + those the ET_EXEC randomisation is the most relevant. Adamantix ships + with mostly ET_DYN executables, so the ET_EXEC randomisation is not + very relevant, but the ET_DYN randomisation is. + + Normally ET_DYN randomisation is bigger than the ET_EXEC randomisation. + +Main executable randomisation (ET_EXEC) +Main executable randomisation (ET_DYN) + + Same here, two tests, because the two different types of executables + can have different randomisation. + +Shared library randomisation test + + Shared libraries can be located at random addresses too, which is what + this test tries to find out. + +Stack randomisation test (SEGMEXEC) +Stack randomisation test (PAGEEXEC) + + The stack is used for storing intermediate data. It also contains + addresses that influence the way programs run. That combination makes + the stack a popular memory area for attacks. Randomisation makes it + harder though, which is what these test try to find out. + +Return to function (strcpy) +Return to function (strcpy, RANDEXEC) +Return to function (memcpy) +Return to function (memcpy, RANDEXEC) + + Return to function attacks are very nasty. These tests are hard to + stop by kernel patches, but they show that there you should not expect + perfect protection from this kind of security patches. + +Executable shared library bss +Executable shared library data + + These tests try to overwrite two different data areas in a shared + library. After that, it tries to execute the data as if it was code. + +Writable text segments + + When an attacker can overwrite code, he can basically alter the + program while it runs. This test tries to do that. + + +Perfect protection: +------------------ +Perfect protection is not possible. That is also the reason why there are +so called return to function tests in paxtest. PaX does not prevent return to +function attacks. Neither do any of the other memory protection patches. But it +is important that people who use kernel patches like PaX do not get a false +sense of security. As the PaX documentation points out: There are three +different classes of attacks, and at this moment PaX can only guarantee +protection against one of them. + + +Further reading: +--------------- +PaX home page: +http://pax.grsecurity.net/ + +PaX mailing list: +http://lists.adamantix.org/ + +PaX documentation (also a thorough introduction into memory protection): +http://pax.grsecurity.net/docs/ + +An article I wrote about PaX has been published in Linux Magazine. The whole +article is available on-line as PDF. It is not very technical, but describes +what memory protection is and why it is important. It can be found here: +http://www.linux-magazine.com/issue/40 + diff --git a/default/paxtest/anonmap.c b/default/paxtest/anonmap.c new file mode 100644 index 0000000..626e5eb --- /dev/null +++ b/default/paxtest/anonmap.c @@ -0,0 +1,42 @@ +/* anonmap.c - Tests whether code can be executed in anonymous mappings + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/mman.h> +#include "body.h" +#include "shellcode.h" + +const char testname[] = "Executable anonymous mapping "; + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + +void doit( void ) +{ + char *buf; + fptr func; + + buf = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if( buf == MAP_FAILED ) { + fprintf( stderr, "mmap() returned NULL\n" ); + exit( 1 ); + } + + copy_shellcode(buf, SHELLCODE_RETURN); + + /* Convert the pointer to a function pointer */ + func = (fptr)buf; + + /* Call the code in the buffer */ + func(); + + /* It worked when the function returns */ + itworked(); +} diff --git a/default/paxtest/body.c b/default/paxtest/body.c new file mode 100644 index 0000000..a85046b --- /dev/null +++ b/default/paxtest/body.c @@ -0,0 +1,109 @@ +/* body.c - This part is shared by the test programs (except for the randomisation + * tests) + * + * Copyright (c)2003,2004 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/mman.h> +#include <unistd.h> +#include <errno.h> +#include <limits.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <pthread.h> +#include <unistd.h> + +extern int doit( void ); +extern const char testname[]; + +static void *test_thread(void *p) +{ + pause(); + return NULL; +} + +int main( int argc, char *argv[] ) +{ + int status; + char *mode; + /* This defaults to 1 as a safety mechanism. It is better to fail in + * blackhat mode, because kiddie mode can produce overly optimistic + * results. + */ + int paxtest_mode = 1; + + /* Dummy nested function */ + void dummy(void) {} + + mode = getenv( "PAXTEST_MODE" ); + if( mode == NULL ) { + paxtest_mode = 1; + } else { + if( strcmp(mode,"0") == 0 ) { + paxtest_mode = 0; + } else if( strcmp(mode,"1") == 0 ) { + paxtest_mode = 1; + } + } + + printf( "%s: ", testname ); + fflush( stdout ); + + if( fork() == 0 ) { + /* Perform a dirty (but not unrealistic) trick to circumvent + * the kernel protection. + */ + if( paxtest_mode == 1 ) { + pthread_t thread; + pthread_create(&thread, NULL, test_thread, dummy); + doit(); + pthread_kill(thread, SIGTERM); + } else { + doit(); + } + } else { + wait( &status ); + if( WIFEXITED(status) == 0 ) { + printf( "Killed\n" ); + exit( 0 ); + } + } + + exit( 0 ); +} + +void itworked( void ) +{ + printf( "Vulnerable\n" ); + exit( 1 ); +} + +void itfailed( void ) +{ + printf( "Ok\n" ); + exit( 2 ); +} + + +int do_mprotect( const void *addr, size_t len, int prot ) +{ + void *ptr; + int retval; + long PAGESIZE = sysconf(_SC_PAGESIZE); + + /* Allign to a multiple of PAGESIZE, assumed to be a power of two */ + ptr = (char *)(((unsigned long) addr) & ~(PAGESIZE-1)); + + retval = mprotect( ptr, len, prot ); + if( retval != 0 && errno == EINVAL ) { + perror( "could not mprotect():" ); + exit( 1 ); + } + + return retval; +} + diff --git a/default/paxtest/body.h b/default/paxtest/body.h new file mode 100644 index 0000000..36ed9d2 --- /dev/null +++ b/default/paxtest/body.h @@ -0,0 +1,4 @@ +void itworked( void ); +void itfailed( void ); +int do_mprotect( const void *addr, size_t len, int prot ); +typedef void (*fptr)(void); diff --git a/default/paxtest/chpax-0.7/Changelog b/default/paxtest/chpax-0.7/Changelog new file mode 100644 index 0000000..4524616 --- /dev/null +++ b/default/paxtest/chpax-0.7/Changelog @@ -0,0 +1,21 @@ + * + * Nov 2002 : Added multi{options,files} cmdline, zeroflag, nicer output + * (+ double output if flags are changed and -v is specified), more error + * handling, more explicit error messages and return values + * + * Jan 2003 : Packaging, Port to Sparc/ELF64 : flags now stand in e_ident[EI_PAX] and + * e_ident[EI_PAX + 1], old chpax version is needed for clearing old flags . + * + * Feb 2003: Added alpha support. + * + * Mar 2003: Added parisc support. + * + * Apr 2003: Added ppc support. + * + * Oct 2003: Added amd64, ia64 and make install support, short format flags printout. + * + * Dec 2003: Added mips and mips64 support. + * + * Feb 2004: Added PT_PAX_FLAGS support. + * + * Jun 2004: Fixed elf.h include, uses glibc's version now, added ppc64 support. diff --git a/default/paxtest/chpax-0.7/Makefile b/default/paxtest/chpax-0.7/Makefile new file mode 100644 index 0000000..4b907b1 --- /dev/null +++ b/default/paxtest/chpax-0.7/Makefile @@ -0,0 +1,33 @@ +## +## Makefile for chpax.c +## +## The PaX project : http://pax.grsecurity.net/ +## + +SRC = chpax.c io.c elf32.c elf64.c aout.c flags.c +OBJ = $(SRC:.c=.o) +RM = rm -f +TARGET = chpax +CC = gcc +CFLAGS = -Wall -W -g3 +STRIP = strip +#STRIP = touch +CP = cp +DESTDIR = +MANDIR = /usr/share/man/man1/ +MKDIR = mkdir -p + +all : $(OBJ) + $(CC) $(CFLAGS) $(OBJ) -o $(TARGET) + +install : all + $(STRIP) $(TARGET) + $(MKDIR) $(DESTDIR)/sbin/ $(DESTDIR)$(MANDIR) + $(CP) $(TARGET) $(DESTDIR)/sbin/ + $(CP) $(TARGET).1 $(DESTDIR)$(MANDIR) + +clean : + $(RM) *.o *~ \#* *\# + +fclean : clean + $(RM) $(TARGET) diff --git a/default/paxtest/chpax-0.7/README b/default/paxtest/chpax-0.7/README new file mode 100644 index 0000000..5c3c7cd --- /dev/null +++ b/default/paxtest/chpax-0.7/README @@ -0,0 +1,11 @@ + + ----------------- + CHPAX README FILE + ----------------- + +As you can see, chpax has been partially rewritten . Since ELF64 is now +supported (so that we match the Linux-PAX/sparc64 needs), we had to start +a modularization of the code . + +For all the technical details about the improvements, check the +Changelog file . diff --git a/default/paxtest/chpax-0.7/aout.c b/default/paxtest/chpax-0.7/aout.c new file mode 100644 index 0000000..26ba7b5 --- /dev/null +++ b/default/paxtest/chpax-0.7/aout.c @@ -0,0 +1,18 @@ +/* +** aout.c for chpax +** +** The PaX project : http://pax.grsecurity.net/ +** +*/ +#include "chpax.h" + + +unsigned long get_flags_aout() +{ + return (N_FLAGS(header_aout)); +} + +void put_flags_aout(unsigned long flags) +{ + N_SET_FLAGS(header_aout, flags & ~HF_PAX_RANDMMAP); +} diff --git a/default/paxtest/chpax-0.7/chpax.1 b/default/paxtest/chpax-0.7/chpax.1 new file mode 100644 index 0000000..5d6e144 --- /dev/null +++ b/default/paxtest/chpax-0.7/chpax.1 @@ -0,0 +1,80 @@ +.\" -*- nroff -*- +.\" +.\" chpax.1 +.\" +.\" This program was written by +.\" The PaX Team <pageexec@xxxxxxxxxxx> +.\" +.\" This manpage was created by: +.\" Martin Krafft <madduck@xxxxxxxxxx< +.\" +.\" The license of this manpage is "Do what you want, but do it right!" +.\" +.TH chpax 1 .\" "chpax Manual" "Feb 12, 2003" +.SH NAME +\fB chpax \fR - user-space utility to control PaX flags +.SH SYNTAX +\fB chpax \fR [-PpEeMmRrXxSsvz] <FILE1> [<FILE2> ...] +.SH DESCRIPTION +\fBchpax\fR is a tool that allows PaX flags to be modified +on a per-binary basis. PaX is part of common security-enhancing +kernel patches, like GrSecurity. Your system needs to be +running an appropriately patched kernel for this program to +have any effect. +.TP +\fB-P\fR +enforce paging based non-executable pages +.TP +\fB-p\fR +do not enforce paging based non-executable pages +.TP +\fB-E\fR +emulate trampolines +.TP +\fB-e\fR +do not emulate trampolines +.TP +\fB-M\fR +restrict mprotect() +.TP +\fB-m\fR +do not restrict mprotect() +.TP +\fB-R\fR +randomize mmap() base +.TP +\fB-r\fR +do not randomize mmap() base +.TP +\fB-X\fR +randomize ET_EXEC base +.TP +\fB-x\fR +do not randomize ET_EXEC base +.TP +\fB-S\fR +enforce segmentation based non-executable pages +.TP +\fB-s\fR +do not enforce segmentation based non-executable pages +.TP +\fB-v\fR +view current flag mask +.TP +\fB-z\fR +zero flag mask (next flags still apply) +.SH CAVEATS +\fBchpax\fR does not currently parse standard command line arguments. Only the +first argument is parsed, and it must contain all of the above flags you +wish to use. So, instead of, e.g., "-v -p -r" you have to use "-vpr". +.SH AUTHOR +Written by The PaX Team <pageexec@xxxxxxxxxxx> +.PP +This manpage was written by Martin F. Krafft <madduck@xxxxxxxxxx> +for the Debian GNU/Linux Distribution, but may be used by others. +.SH "SEE ALSO" +.BR gradm (1) +.PP +The PaX website: http://pax.grsecurity.net +.PP +The GrSecurity website: http://www.grsecurity.net diff --git a/default/paxtest/chpax-0.7/chpax.c b/default/paxtest/chpax-0.7/chpax.c new file mode 100644 index 0000000..42ba7b4 --- /dev/null +++ b/default/paxtest/chpax-0.7/chpax.c @@ -0,0 +1,97 @@ +/* + * chpax version 0.7 + * + * This program manages various PaX related flags for ELF32, ELF64, + * and a.out binaries. The flags only have effect when running the + * patched Linux kernel. + * + * Written by Solar Designer and placed in the public domain. + * + * Adapted to PaX by the PaX Team + * + * Maintained by [jv@xxxxxxxxxxxxxx] + * + */ +#include "chpax.h" + +Elf32_Ehdr header_elf; +Elf64_Ehdr header_elf64; +struct exec header_aout; +int header_size; +void *header; +int fd; +unsigned long (*get_flags)(); +void (*put_flags)(unsigned long); + + +int main(int argc, char *argv[]) +{ + unsigned long flags; + unsigned long aflags; + unsigned int index = 2; + int mode; + char *current; + int error = 0; + int view = 0; + + if (!argv) + usage(NULL); + if (argc < 3 || !argv[1] || argv[1][0] != '-') + usage(argv[0]); + + flags = scan_flags(0, argv, &view); + mode = view & !flags ? O_RDONLY : O_RDWR; + + for (current = argv[index]; current; current = argv[++index]) + { + + error = read_header(current, mode); + switch (error) + { + case 1: + perror(current); + continue ; + case 2: + fprintf(stderr, "%s: Unknown file type (passed) \n", current); + XCLOSE(fd); + continue ; + case 3: + fprintf(stderr, "%s: Wrong architecture (passed) \n", current); + XCLOSE(fd); + continue ; + } + + aflags = get_flags(); + flags = scan_flags(aflags, argv, &view); + + if (view) + { + printf("\n----[ chpax %s : Current flags for %s (%s) ]---- \n\n", + CHPAX_VERSION, current, pax_short_flags(aflags)); + print_flags(aflags); + puts(""); + } + + put_flags(flags); + + if (flags != aflags && write_header()) + { + perror(current); + error = 4; + } + + if (error) + fprintf(stderr, "%s : Flags were not updated . \n", current); + else if (view && aflags != flags) + { + printf("\n----[ chpax %s : Updated flags for %s (%s) ]---- \n\n", + CHPAX_VERSION, current, pax_short_flags(flags)); + print_flags(flags); + puts(""); + } + + XCLOSE(fd); + } + + return (error); +} diff --git a/default/paxtest/chpax-0.7/chpax.h b/default/paxtest/chpax-0.7/chpax.h new file mode 100644 index 0000000..5b03a08 --- /dev/null +++ b/default/paxtest/chpax-0.7/chpax.h @@ -0,0 +1,77 @@ +/* + * Include file for chpax.c + * + * The PaX project : http://pax.grsecurity.net/ + * + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> +#include <unistd.h> +#include <elf.h> +#include <a.out.h> + +#define CHPAX_VERSION "0.7" + +#define HF_PAX_PAGEEXEC 1 /* 0: Paging based non-exec pages */ +#define HF_PAX_EMUTRAMP 2 /* 0: Emulate trampolines */ +#define HF_PAX_MPROTECT 4 /* 0: Restrict mprotect() */ +#define HF_PAX_RANDMMAP 8 /* 0: Randomize mmap() base */ +#define HF_PAX_RANDEXEC 16 /* 1: Randomize ET_EXEC base */ +#define HF_PAX_SEGMEXEC 32 /* 0: Segmentation based non-exec pages */ + +#define EI_PAX 14 /* Index to read the PaX flags into ELF header e_ident[] array */ + +#ifndef PT_PAX_FLAGS +#define PT_PAX_FLAGS 0x65041580 /* Indicates PaX flag markings */ +#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 */ +#endif + +#define XCLOSE(fd) \ +do \ +{ \ + if (close(fd)) \ + perror("close"); \ +} \ +while (0) + +#define FILE_IS_ELF64(h) (h.e_ident[EI_CLASS] == 2) +#define FILE_IS_ELF32(h) (h.e_ident[EI_CLASS] == 1) + +/* Extern variables */ +extern Elf32_Ehdr header_elf; +extern Elf64_Ehdr header_elf64; +extern struct exec header_aout; +extern int header_size; +extern void *header; +extern int fd; +extern unsigned long (*get_flags)(); +extern void (*put_flags)(unsigned long); + +/* Function prototypes */ +int read_header(char *name, int flags); +int write_header(); +unsigned long get_flags_elf(); +void put_flags_elf(unsigned long flags); +unsigned long get_flags_aout(); +void put_flags_aout(unsigned long flags); +unsigned long get_flags_elf64(); +void put_flags_elf64(unsigned long flags); +void usage(char *name); +unsigned long scan_flags(unsigned long flags, char **argv, int *view); +void print_flags(unsigned long flags); +char *pax_short_flags(unsigned long flags); diff --git a/default/paxtest/chpax-0.7/elf32.c b/default/paxtest/chpax-0.7/elf32.c new file mode 100644 index 0000000..50208aa --- /dev/null +++ b/default/paxtest/chpax-0.7/elf32.c @@ -0,0 +1,22 @@ +/* +** elf32.c for chpax +** +** The PaX project : http://pax.grsecurity.net/ +** +*/ +#include "chpax.h" + + +unsigned long get_flags_elf() +{ + u_long flags; + + flags = ((u_long) header_elf.e_ident[EI_PAX + 1] << 8) + (u_long) header_elf.e_ident[EI_PAX]; + return (flags); +} + +void put_flags_elf(unsigned long flags) +{ + header_elf.e_ident[EI_PAX] = (flags & 0xFF); + header_elf.e_ident[EI_PAX + 1] = ((flags >> 8) & 0xFF); +} diff --git a/default/paxtest/chpax-0.7/elf64.c b/default/paxtest/chpax-0.7/elf64.c new file mode 100644 index 0000000..6633190 --- /dev/null +++ b/default/paxtest/chpax-0.7/elf64.c @@ -0,0 +1,22 @@ +/* +** elf64.c for chpax +** +** The PaX project : http://pax.grsecurity.net/ +** +*/ +#include "chpax.h" + +unsigned long get_flags_elf64() +{ + u_long flags; + + flags = ((u_long) header_elf64.e_ident[EI_PAX + 1] << 8) + (u_long) header_elf.e_ident[EI_PAX]; + return (flags); +} + +void put_flags_elf64(unsigned long flags) +{ + header_elf64.e_ident[EI_PAX] = (flags & 0xFF); + header_elf64.e_ident[EI_PAX + 1] = ((flags >> 8) & 0xFF); +} + diff --git a/default/paxtest/chpax-0.7/flags.c b/default/paxtest/chpax-0.7/flags.c new file mode 100644 index 0000000..73e9c8a --- /dev/null +++ b/default/paxtest/chpax-0.7/flags.c @@ -0,0 +1,147 @@ +/* +** flags.c for chpax +** +** The PaX project : http://pax.grsecurity.net/ +** +*/ +#include "chpax.h" + + +#define USAGE \ +"%s %s .::. Manage PaX flags for binaries\n" \ +"Usage: %s OPTIONS FILE1 FILE2 FILEN ...\n" \ +" -P\tenforce paging based non-executable pages\n" \ +" -p\tdo not enforce paging based non-executable pages\n" \ +" -E\temulate trampolines\n" \ +" -e\tdo not emulate trampolines\n" \ +" -M\trestrict mprotect()\n" \ +" -m\tdo not restrict mprotect()\n" \ +" -R\trandomize mmap() base [ELF only]\n" \ +" -r\tdo not randomize mmap() base [ELF only]\n" \ +" -X\trandomize ET_EXEC base [ELF only]\n" \ +" -x\tdo not randomize ET_EXEC base [ELF only]\n" \ +" -S\tenforce segmentation based non-executable pages\n" \ +" -s\tdo not enforce segmentation based non-executable pages\n" \ +" -v\tview current flag mask \n" \ +" -z\tzero flag mask (next flags still apply)\n\n" \ +"The flags only have effect when running the patched Linux kernel.\n" \ + + +void usage(char *name) +{ + char *ptr; + + ptr = (name ? name : "chpax"); + printf(USAGE, ptr, CHPAX_VERSION, ptr); + exit(1); +} + + +unsigned long scan_flags(unsigned long flags, char **argv, int *view) +{ + int index; + + for (index = 1; argv[1][index]; index++) + switch (argv[1][index]) + { + + case 'p': + flags |= HF_PAX_PAGEEXEC; + continue ; + + case 'P': + flags = (flags & ~HF_PAX_PAGEEXEC) | HF_PAX_SEGMEXEC; + continue ; + + case 'E': + flags |= HF_PAX_EMUTRAMP; + continue ; + + case 'e': + flags = (flags & ~HF_PAX_EMUTRAMP); + continue ; + + case 'm': + flags |= HF_PAX_MPROTECT; + continue ; + + case 'M': + flags = (flags & ~HF_PAX_MPROTECT); + continue ; + + case 'r': + flags |= HF_PAX_RANDMMAP; + continue ; + + case 'R': + flags = (flags & ~HF_PAX_RANDMMAP); + continue ; + + case 'X': + flags |= HF_PAX_RANDEXEC; + continue ; + + case 'x': + flags = (flags & ~HF_PAX_RANDEXEC); + continue ; + + case 's': + flags |= HF_PAX_SEGMEXEC; + continue ; + + case 'S': + flags = (flags & ~HF_PAX_SEGMEXEC) | HF_PAX_PAGEEXEC; + continue ; + + case 'v': + *view = 1; + continue ; + + case 'z': + flags = 0; + continue ; + + default: + fprintf(stderr, "Unknown option %c \n", argv[1][index]); + usage(argv[0]); + } + + return (flags); +} + + +char *pax_short_flags(unsigned long flags) +{ + static char buffer[7]; + + buffer[0] = (flags & HF_PAX_PAGEEXEC ? 'p' : 'P'); + buffer[1] = (flags & HF_PAX_EMUTRAMP ? 'E' : 'e'); + buffer[2] = (flags & HF_PAX_MPROTECT ? 'm' : 'M'); + buffer[3] = (flags & HF_PAX_RANDMMAP ? 'r' : 'R'); + buffer[4] = (flags & HF_PAX_RANDEXEC ? 'X' : 'x'); + buffer[5] = (flags & HF_PAX_SEGMEXEC ? 's' : 'S'); + return buffer; +} + + +void print_flags(unsigned long flags) +{ + printf(" * Paging based PAGE_EXEC : %s \n" + " * Trampolines : %s \n" + " * mprotect() : %s \n" + " * mmap() base : %s \n" + " * ET_EXEC base : %s \n" + " * Segmentation based PAGE_EXEC : %s \n", + flags & HF_PAX_PAGEEXEC + ? "disabled" : flags & HF_PAX_SEGMEXEC ? "enabled" : "enabled (overridden)", + flags & HF_PAX_EMUTRAMP + ? "emulated" : "not emulated", + flags & HF_PAX_MPROTECT + ? "not restricted" : "restricted", + flags & HF_PAX_RANDMMAP + ? "not randomized" : "randomized", + flags & HF_PAX_RANDEXEC + ? "randomized" : "not randomized", + flags & HF_PAX_SEGMEXEC + ? "disabled" : "enabled"); +} diff --git a/default/paxtest/chpax-0.7/io.c b/default/paxtest/chpax-0.7/io.c new file mode 100644 index 0000000..0c8d78d --- /dev/null +++ b/default/paxtest/chpax-0.7/io.c @@ -0,0 +1,118 @@ +/* +** io.c for chpax +** +** The PaX project : http://pax.grsecurity.net/ +** +*/ +#include "chpax.h" + +#ifndef EM_X86_64 +#define EM_X86_64 62 +#endif + +/* Read flags */ +int read_header(char *name, int flags) +{ + char *ptr; + int size; + int block; + + if ((fd = open(name, flags)) < 0) + return 1; + + ptr = (char *) &header_elf64; + size = sizeof(header_elf64); + + do + { + block = read(fd, ptr, size); + if (block <= 0) + return (block ? 1 : 2); + ptr += block; + size -= block; + } + while (size > 0); + + memcpy(&header_aout, &header_elf64, sizeof(header_aout)); + memcpy(&header_elf, &header_elf64, sizeof(header_elf)); + + if (!memcmp(header_elf64.e_ident, ELFMAG, SELFMAG) && FILE_IS_ELF64(header_elf64)) + { + if (header_elf64.e_type != ET_EXEC && header_elf.e_type != ET_DYN) + return 2; + if (header_elf64.e_machine != EM_SPARC && + header_elf64.e_machine != EM_SPARCV9 && + header_elf64.e_machine != EM_ALPHA && + header_elf64.e_machine != EM_X86_64 && + header_elf64.e_machine != EM_IA_64 && + header_elf64.e_machine != EM_PPC64) + return 3; + header = &header_elf64; + header_size = sizeof(header_elf64); + get_flags = get_flags_elf64; + put_flags = put_flags_elf64; + } + + else if (!memcmp(header_elf.e_ident, ELFMAG, SELFMAG) && FILE_IS_ELF32(header_elf)) + { + if (header_elf.e_type != ET_EXEC && header_elf.e_type != ET_DYN) + return 2; + if (header_elf.e_machine != EM_386 && + header_elf.e_machine != EM_SPARC && + header_elf.e_machine != EM_SPARC32PLUS && + header_elf.e_machine != EM_PARISC && + header_elf.e_machine != EM_PPC && + header_elf.e_machine != EM_MIPS && + header_elf.e_machine != EM_MIPS_RS3_LE) + return 3; + header = &header_elf; + header_size = sizeof(header_elf); + get_flags = get_flags_elf; + put_flags = put_flags_elf; + } + + else if (N_MAGIC(header_aout) == NMAGIC || + N_MAGIC(header_aout) == ZMAGIC || + N_MAGIC(header_aout) == QMAGIC) + { + + if (N_MACHTYPE(header_aout) != M_386) + return 3; + header = &header_aout; + header_size = 4; + get_flags = get_flags_aout; + put_flags = put_flags_aout; + } + + else + return (2); + + return (0); +} + + +/* Write flags */ +int write_header() +{ + char *ptr; + int size; + int block; + + if ((off_t)-1 == lseek(fd, 0, SEEK_SET)) + return 1; + + ptr = (char *) header; + size = header_size; + + do + { + block = write(fd, ptr, size); + if (block <= 0) + break; + ptr += block; + size -= block; + } + while (size > 0); + + return size; +} diff --git a/default/paxtest/crt1S.S b/default/paxtest/crt1S.S new file mode 100644 index 0000000..c98b95e --- /dev/null +++ b/default/paxtest/crt1S.S @@ -0,0 +1,57 @@ + .text + .globl _start + .type _start,@function +_start: + popl %esi + movl %esp, %ecx + andl $0xfffffff0, %esp + call .L1 +.L1: + pop %ebp + addl $_GLOBAL_OFFSET_TABLE_+[.-.L1],%ebp + pushl %eax + pushl %esp + pushl %edx + pushl _fini@GOT(%ebp) + pushl _init@GOT(%ebp) + pushl %ecx + pushl %esi + pushl main@GOT(%ebp) + pushl .hlt@GOT(%ebp) + pushl __libc_start_main@GOT(%ebp) + xorl %ebp, %ebp + ret +.hlt: + hlt + + .section .rodata + .globl _fp_hw +_fp_hw: .long 3 + .size _fp_hw, 4 + .type _fp_hw,@object + + .data + .globl __data_start +__data_start: + .long 0 + .weak data_start + data_start = __data_start + + .section ".note.ABI-tag", "a" + .align 4 + .long 1f - 0f + .long 3f - 2f + .long 1 +0: .asciz "GNU" +1: .align 4 +2: .long 0 + .long 2,0,0 +3: .align 4 + + .section .rodata + .globl _IO_stdin_used + .align 4 +_IO_stdin_used: + .long 0x20001 + .size _IO_stdin_used,4 + .type _IO_stdin_used,@object diff --git a/default/paxtest/debian/changelog b/default/paxtest/debian/changelog new file mode 100644 index 0000000..b9f4872 --- /dev/null +++ b/default/paxtest/debian/changelog @@ -0,0 +1,75 @@ +paxtest (0.9.9--3) stable; urgency=low + * fixed Makefile to use -nopie for Gentoo Hardened on ET_EXEC tests + +paxtest (0.9.9-2) stable; urgency=low + * fixed writable text segments test under gcc 4.5 optimizations + +paxtest (0.9.9-1) stable; urgency=low + * added SPARC/64 support + * added PPC/64 support (return to function tests should be ignored for PPC64) + * added 32/64bit target support + * added shellode.h to easily support additional architectures + * made paxctl generate the PT_PAX_FLAGS header for binaries that + didn't have one + +paxtest (0.9.7-1) stable; urgency=low + * Fixed some tests on OpenBSD and FreeBSD (thanks to paxtest@xxxxxxxxx + and mux@xxxxxxxxxxx) + * Fixed return address acquisition, still gcc specific + * Switched to paxctl on gentoo + * Fixed setting up LD_LIBRARY_PATH in genpaxtest (Peter S. Mazinger) + * Added uClibc support (Peter S. Mazinger) + * Fixed the executable shared library data/bss tests (thanks to + paxtest@xxxxxxxxx) + +paxtest (0.9.6-1) stable; urgency=low + + * Made the do_mprotect() call in body.c optional, thereby introducing two + modes: script kiddie mode (which does not perform the do_mprotect()) and + blackhat mode, which does. + * Added a README file + * Added Adamantix paxtest results + * Removed -etdyn from the Adamantix make file + * Replaced mprotect() in body.c with pthread calls (which eventually have + the same result) + * Added a nested function, to measure the effect of nested functions on the + level of protection. + * Added paxtest result from Gentoo hardened (thanks to Ned Ludd) + * Added a new Makefile for Gentoo (thanks to Ned Ludd) + * Fixed spelling errors (thanks to pageexec@xxxxxxxxxxx) + + -- Peter Busser <peter@xxxxxxxxxxxxxxxxxxxx> Wed, 25 Feb 2004 20:24:53 +0200 + +paxtest (0.9.5-1) unstable; urgency=low + + * Fixed the shlibbss and shlibdata tests (pageexec@xxxxxxxxxxx) + * Non-executable page tests expose incomplete implementations + (pageexec@xxxxxxxxxxx) + + -- Peter Busser <peter@xxxxxxxxxxxxx> Tue, 04 Nov 2003 16:37:26 +0200 + +paxtest (0.9.4-1) unstable; urgency=low + + * Fixed mprotanon (pageexec@xxxxxxxxxxx) + * Fixed rettofunc[12] (pageexec@xxxxxxxxxxx) + * Fixed shared library data/bss tests (pageexec@xxxxxxxxxxx) + * Introduced return-to-libc detection as proof-of-concept + (pageexec@xxxxxxxxxxx) + + -- Peter Busser <peter@xxxxxxxxxxxxx> Tue, 22 Oct 2003 21:00:05 +0200 + +paxtest (0.9.3-1) unstable; urgency=low + + * Changed e-mail addresses in source files to peter@xxxxxxxxxxxxx + * Added copyright message printing in the run script. + * Upgraded to chpax v0.5 (pageexec@xxxxxxxxxxx) + * Split randheap in two parts, one as ET_EXEC and the other as ET_DYN + + -- Peter Busser <peter@xxxxxxxxxxxxx> Sun, 12 Oct 2003 10:58:52 +0200 + +paxtest (0.9.0-1) unstable; urgency=low + + * Initial Release. + + -- Peter Busser <peter@xxxxxxxxxxxxxxxxx> Mon, 19 May 2003 13:44:39 +0200 + diff --git a/default/paxtest/debian/control b/default/paxtest/debian/control new file mode 100644 index 0000000..194da0e --- /dev/null +++ b/default/paxtest/debian/control @@ -0,0 +1,24 @@ +Source: paxtest +Section: main +Priority: optional +Maintainer: Peter Busser <peter@xxxxxxxxxxxxx> +Build-Depends: debhelper (>> 3.0.0), gcc, binutils +Standards-Version: 3.5.2 + +Package: paxtest +Architecture: i386 +Depends: ${shlibs:Depends} +Description: a-: Test suite for the PaX kernel patch + PaX is a Linux kernel patch which adds much stricter control on how memory + is being used by applications. A normal Linux kernel leaves the control to the + application and does not implement any enforcement. Especially buffer overflow + attacks benefit from the absense of kernel enforced memory control. PaX tries + to do its best to enforce this control of memory used by applications, thereby + making it harder to successfully exploit buffer overflows. + . + Paxtest provides a regression test suite that covers most (but not all) + of PaX functionality. It can also be used to test other memory protection + patches. + . + For more information about PaX, see http://pax.grsecurity.net/. + diff --git a/default/paxtest/debian/copyright b/default/paxtest/debian/copyright new file mode 100644 index 0000000..862ec95 --- /dev/null +++ b/default/paxtest/debian/copyright @@ -0,0 +1,8 @@ +paxtest is copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + +Paxtest is licened under the terms of the GNU General Public License (GPL), +version 2.0 or later, as published by the Free Software Foundation. See +the file COPYING [included], /usr/share/common-licenses/GPL, or +<http://www.gnu.org/copyleft/gpl.txt> for the terms of the latest version +of the GNU General Public License. + diff --git a/default/paxtest/debian/dirs b/default/paxtest/debian/dirs new file mode 100644 index 0000000..ca882bb --- /dev/null +++ b/default/paxtest/debian/dirs @@ -0,0 +1,2 @@ +usr/bin +usr/sbin diff --git a/default/paxtest/debian/docs b/default/paxtest/debian/docs new file mode 100644 index 0000000..5b5d593 --- /dev/null +++ b/default/paxtest/debian/docs @@ -0,0 +1,5 @@ +COPYING +README +results/Results.README +results/Adamantix.kiddie +results/Adamantix.blackhat diff --git a/default/paxtest/debian/manpage.1.ex b/default/paxtest/debian/manpage.1.ex new file mode 100644 index 0000000..125432b --- /dev/null +++ b/default/paxtest/debian/manpage.1.ex @@ -0,0 +1,60 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH PAXTEST SECTION "May 19, 2003" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp <n> insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +paxtest \- program to do something +.SH SYNOPSIS +.B paxtest +.RI [ options ] " files" ... +.br +.B bar +.RI [ options ] " files" ... +.SH DESCRIPTION +This manual page documents briefly the +.B paxtest +and +.B bar +commands. +This manual page was written for the Debian distribution +because the original program does not have a manual page. +Instead, it has documentation in the GNU Info format; see below. +.PP +.\" TeX users may be more comfortable with the \fB<whatever>\fP and +.\" \fI<whatever>\fP escape sequences to invode bold face and italics, +.\" respectively. +\fBpaxtest\fP is a program that... +.SH OPTIONS +These programs follow the usual GNU command line syntax, with long +options starting with two dashes (`-'). +A summary of options is included below. +For a complete description, see the Info files. +.TP +.B \-h, \-\-help +Show summary of options. +.TP +.B \-v, \-\-version +Show version of program. +.SH SEE ALSO +.BR bar (1), +.BR baz (1). +.br +The programs are documented fully by +.IR "The Rise and Fall of a Fooish Bar" , +available via the Info system. +.SH AUTHOR +This manual page was written by Peter Busser <peter@dev>, +for the Debian GNU/Linux system (but may be used by others). diff --git a/default/paxtest/debian/manpage.sgml.ex b/default/paxtest/debian/manpage.sgml.ex new file mode 100644 index 0000000..e878798 --- /dev/null +++ b/default/paxtest/debian/manpage.sgml.ex @@ -0,0 +1,152 @@ +<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [ + +<!-- Process this file with docbook-to-man to generate an nroff manual + page: `docbook-to-man manpage.sgml > manpage.1'. You may view + the manual page with: `docbook-to-man manpage.sgml | nroff -man | + less'. A typical entry in a Makefile or Makefile.am is: + +manpage.1: manpage.sgml + docbook-to-man $< > $@ + + + The docbook-to-man binary is found in the docbook-to-man package. + Please remember that if you create the nroff version in one of the + debian/rules file targets (such as build), you will need to include + docbook-to-man in your Build-Depends control field. + + --> + + <!-- Fill in your name for FIRSTNAME and SURNAME. --> + <!ENTITY dhfirstname "<firstname>FIRSTNAME</firstname>"> + <!ENTITY dhsurname "<surname>SURNAME</surname>"> + <!-- Please adjust the date whenever revising the manpage. --> + <!ENTITY dhdate "<date>May 19, 2003</date>"> + <!-- SECTION should be 1-8, maybe w/ subsection other parameters are + allowed: see man(7), man(1). --> + <!ENTITY dhsection "<manvolnum>SECTION</manvolnum>"> + <!ENTITY dhemail "<email>peter@dev</email>"> + <!ENTITY dhusername "Peter Busser"> + <!ENTITY dhucpackage "<refentrytitle>PAXTEST</refentrytitle>"> + <!ENTITY dhpackage "paxtest"> + + <!ENTITY debian "<productname>Debian</productname>"> + <!ENTITY gnu "<acronym>GNU</acronym>"> +]> + +<refentry> + <refentryinfo> + <address> + &dhemail; + </address> + <author> + &dhfirstname; + &dhsurname; + </author> + <copyright> + <year>2001</year> + <holder>&dhusername;</holder> + </copyright> + &dhdate; + </refentryinfo> + <refmeta> + &dhucpackage; + + &dhsection; + </refmeta> + <refnamediv> + <refname>&dhpackage;</refname> + + <refpurpose>program to do something</refpurpose> + </refnamediv> + <refsynopsisdiv> + <cmdsynopsis> + <command>&dhpackage;</command> + + <arg><option>-e <replaceable>this</replaceable></option></arg> + + <arg><option>--example <replaceable>that</replaceable></option></arg> + </cmdsynopsis> + </refsynopsisdiv> + <refsect1> + <title>DESCRIPTION</title> + + <para>This manual page documents briefly the + <command>&dhpackage;</command> and <command>bar</command> + commands.</para> + + <para>This manual page was written for the &debian; distribution + because the original program does not have a manual page. + Instead, it has documentation in the &gnu; + <application>Info</application> format; see below.</para> + + <para><command>&dhpackage;</command> is a program that...</para> + + </refsect1> + <refsect1> + <title>OPTIONS</title> + + <para>These programs follow the usual GNU command line syntax, + with long options starting with two dashes (`-'). A summary of + options is included below. For a complete description, see the + <application>Info</application> files.</para> + + <variablelist> + <varlistentry> + <term><option>-h</option> + <option>--help</option> + </term> + <listitem> + <para>Show summary of options.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><option>-v</option> + <option>--version</option> + </term> + <listitem> + <para>Show version of program.</para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + <refsect1> + <title>SEE ALSO</title> + + <para>bar (1), baz (1).</para> + + <para>The programs are documented fully by <citetitle>The Rise and + Fall of a Fooish Bar</citetitle> available via the + <application>Info</application> system.</para> + </refsect1> + <refsect1> + <title>AUTHOR</title> + + <para>This manual page was written by &dhusername; &dhemail; for + the &debian; system (but may be used by others). Permission is + granted to copy, distribute and/or modify this document under + the terms of the <acronym>GNU</acronym> Free Documentation + License, Version 1.1 or any later version published by the Free + Software Foundation; with no Invariant Sections, no Front-Cover + Texts and no Back-Cover Texts.</para> + + </refsect1> +</refentry> + +<!-- Keep this comment at the end of the file +Local variables: +mode: sgml +sgml-omittag:t +sgml-shorttag:t +sgml-minimize-attributes:nil +sgml-always-quote-attributes:t +sgml-indent-step:2 +sgml-indent-data:t +sgml-parent-document:nil +sgml-default-dtd-file:nil +sgml-exposed-tags:nil +sgml-local-catalogs:nil +sgml-local-ecat-files:nil +End: +--> + + diff --git a/default/paxtest/debian/paxtest.sgml b/default/paxtest/debian/paxtest.sgml new file mode 100644 index 0000000..65e90a0 --- /dev/null +++ b/default/paxtest/debian/paxtest.sgml @@ -0,0 +1,167 @@ +<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [ + + + <!-- Fill in your name for FIRSTNAME and SURNAME. --> + <!ENTITY dhfirstname "<firstname>Javier</firstname>"> + <!ENTITY dhsurname "<surname>Fernandez-Sanguino</surname>"> + <!-- Please adjust the date whenever revising the manpage. --> + <!ENTITY dhdate "<date>November 8, 2003</date>"> + <!-- SECTION should be 1-8, maybe w/ subsection other parameters are + allowed: see man(7), man(1). --> + <!ENTITY dhsection "<manvolnum>1</manvolnum>"> + <!ENTITY dhemail "<email>jfs@xxxxxxxxxxxx</email>"> + <!ENTITY dhusername "Javier Fernandez-Sanguino"> + <!ENTITY dhucpackage "<refentrytitle>PAXTEST</refentrytitle>"> + <!ENTITY dhpackage "paxtest"> + + <!ENTITY debian "<productname>Debian</productname>"> + <!ENTITY gnu "<acronym>GNU</acronym>"> +]> + +<refentry> + <refentryinfo> + <address> + &dhemail; + </address> + <author> + &dhfirstname; + &dhsurname; + </author> + <copyright> + <year>2003</year> + <holder>Peter Busser</holder> + </copyright> + &dhdate; + </refentryinfo> + <refmeta> + &dhucpackage; + + &dhsection; + </refmeta> + <refnamediv> + <refname>&dhpackage;</refname> + + <refpurpose>program to test buffer overflow protection</refpurpose> + </refnamediv> + <refsynopsisdiv> + <cmdsynopsis> + <command>&dhpackage;</command> + + <arg><replaceable>logfile</replaceable></arg> + </cmdsynopsis> + </refsynopsisdiv> + <refsect1> + <title>DESCRIPTION</title> + + <para><command>&dhpackage;</command> is a program that attempts to + test kernel enforcements over memory usage. Some attacks benefit + from kernels that do not impose limitations. For example, execution + in some memory segments makes buffer overflows possible. It is + used as a regression test suite for PaX, but might be useful + to test other memory protection patches for the kernel.</para> + + <para><command>&dhpackage;</command> runs a set of programs that + attempt to subvert memory usage. For example: + </para> + + <literallayout> +Executable anonymous mapping : Killed +Executable bss : Killed +Executable data : Killed +Executable heap : Killed +Executable stack : Killed +Executable anonymous mapping (mprotect) : Killed +Executable bss (mprotect) : Killed +Executable data (mprotect) : Killed +Executable heap (mprotect) : Killed +Executable shared library bss (mprotect) : Killed +Executable shared library data (mprotect): Killed +Executable stack (mprotect) : Killed +Anonymous mapping randomisation test : 16 bits (guessed) +Heap randomisation test (ET_EXEC) : 13 bits (guessed) +Heap randomisation test (ET_DYN) : 25 bits (guessed) +Main executable randomisation (ET_EXEC) : No randomisation +Main executable randomisation (ET_DYN) : 17 bits (guessed) +Stack randomisation test (SEGMEXEC) : 23 bits (guessed) +Stack randomisation test (PAGEEXEC) : 24 bits (guessed) +Return to function (strcpy) : Vulnerable +Return to function (strcpy, RANDEXEC) : Vulnerable +Return to function (memcpy) : Vulnerable +Return to function (memcpy, RANDEXEC) : Vulnerable +Executable shared library bss : Killed +Executable shared library data : Killed +Writable text segments : Killed + </literallayout> + + <para>The <quote>Executable ...</quote> tests basically put an instruction + in a place + that is supposed to be data (i.e. malloced data, C variable, etc.) + and tries to execute it. The <quote>(mprotect)</quote> tests try to trick + the kernel in marking this piece of memory as executable first. + Return to function tests overwrite the return address on the stack, + these are hard to prevent from inside the kernel. + The last test tries to overwrite memory which is marked as executable. + </para> + + <para>A normal Linux kernel (unpatched to protect for buffer overflows) + will show all tests as Vulnerable and no stack + randomisation or 6 bits (due to stack colouring). In other words, + on a normal Linux kernel you can execute any data inside a process's + memory or overwrite any code at will. + </para> + + <para>This manual page was written for the &debian; distribution + because the original program does not have a manual page. + </para> + + + </refsect1> + <refsect1> + <title>OPTIONS</title> + + <para>This program takes only a single option: a file to which + log all the test results (by default it will log to stdin/stdout) + </para> + </refsect1> + <refsect1> + <title>SEE ALSO</title> + + <para>For more information see + <ulink url="http://pax.grsecurity.net/docs">PaX Documentation</ulink>.</para> + + </refsect1> + <refsect1> + <title>AUTHOR</title> + + <para>&dhpackage; was written by Peter Busser.</para> + + <para>This manual page was written by &dhusername; &dhemail; for + the &debian; system (but may be used by others) based on the + information in the source code and Peter Busser's comments + sent to public mailing lists. Permission is + granted to copy, distribute and/or modify this document under + the terms of the <acronym>GNU</acronym> Public License, Version 2 + or any later version published by the Free + Software Foundation.</para> + + </refsect1> +</refentry> + +<!-- Keep this comment at the end of the file +Local variables: +mode: sgml +sgml-omittag:t +sgml-shorttag:t +sgml-minimize-attributes:nil +sgml-always-quote-attributes:t +sgml-indent-step:2 +sgml-indent-data:t +sgml-parent-document:nil +sgml-default-dtd-file:nil +sgml-exposed-tags:nil +sgml-local-catalogs:nil +sgml-local-ecat-files:nil +End: +--> + + diff --git a/default/paxtest/debian/rules b/default/paxtest/debian/rules new file mode 100644 index 0000000..aeb070b --- /dev/null +++ b/default/paxtest/debian/rules @@ -0,0 +1,104 @@ +#!/usr/bin/make -f +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# This is the debhelper compatibility version to use. +export DH_COMPAT=3 + +# +# The directory where the test programs and shared library are going to live +# +RUNDIR=/usr/lib/paxtest +export RUNDIR + +# +# The directory where the test script (paxtest) is going to live +# +BINDIR=/usr/bin +export BINDIR + +ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) + CFLAGS += -g +endif +ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) + INSTALL_PROGRAM += -s +endif + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + + touch configure-stamp + + +build: build-stamp + +build-stamp: configure-stamp + dh_testdir + + # Add here commands to compile the package. + $(MAKE) -f Makefile.Adamantix + #/usr/bin/docbook-to-man debian/paxtest.sgml > paxtest.1 + + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + -$(MAKE) -f Makefile.Adamantix clean + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/paxtest. + $(MAKE) -f Makefile.Adamantix install DESTDIR=$(CURDIR)/debian/paxtest + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot +# dh_installdebconf + dh_installdocs + dh_installexamples + dh_installmenu +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_installinit + dh_installcron + dh_installman + dh_installinfo +# dh_undocumented + dh_installchangelogs + dh_link + dh_strip + dh_compress + dh_fixperms +# dh_makeshlibs + dh_installdeb +# dh_perl + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/default/paxtest/execbss.c b/default/paxtest/execbss.c new file mode 100644 index 0000000..dcf6a54 --- /dev/null +++ b/default/paxtest/execbss.c @@ -0,0 +1,31 @@ +/* execbss.c - Tests whether code in the .bss segment can be executed + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "body.h" +#include "shellcode.h" + +const char testname[] = "Executable bss "; + +char buf[MAX_SHELLCODE_LEN]; + +void doit( void ) +{ + fptr func; + + copy_shellcode(buf, SHELLCODE_RETURN); + + /* Convert the pointer to a function pointer */ + func = (fptr)&buf; + + /* Call the code in the buffer */ + func(); + + /* It worked when the function returns */ + itworked(); +} diff --git a/default/paxtest/execdata.c b/default/paxtest/execdata.c new file mode 100644 index 0000000..46439ab --- /dev/null +++ b/default/paxtest/execdata.c @@ -0,0 +1,31 @@ +/* execdata.c - Tests whether code in the .data segment can be executed + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "body.h" +#include "shellcode.h" + +const char testname[] = "Executable data "; + +char buf[MAX_SHELLCODE_LEN] = SHELLCODE_RETURN_ARRAY; + +void doit( void ) +{ + fptr func; + + copy_shellcode(buf, SHELLCODE_RETURN); + + /* Convert the pointer to a function pointer */ + func = (fptr)&buf; + + /* Call the code in the buffer */ + func(); + + /* It worked when the function returns */ + itworked(); +} diff --git a/default/paxtest/execheap.c b/default/paxtest/execheap.c new file mode 100644 index 0000000..456f0dc --- /dev/null +++ b/default/paxtest/execheap.c @@ -0,0 +1,36 @@ +/* execheap.c - Tests whether code in the heap can be executed + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "body.h" +#include "shellcode.h" + +const char testname[] = "Executable heap "; + +void doit( void ) +{ + char *buf; + fptr func; + + buf = malloc( MAX_SHELLCODE_LEN ); + if( buf == NULL ) { + fprintf( stderr, "Out of memory\n" ); + exit( 1 ); + } + + copy_shellcode(buf, SHELLCODE_RETURN); + + /* Convert the pointer to a function pointer */ + func = (fptr)buf; + + /* Call the code in the buffer */ + func(); + + /* It worked when the function returns */ + itworked(); +} diff --git a/default/paxtest/execstack.c b/default/paxtest/execstack.c new file mode 100644 index 0000000..c63e003 --- /dev/null +++ b/default/paxtest/execstack.c @@ -0,0 +1,30 @@ +/* execstack.c - Tests whether code on the stack can be executed + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "body.h" +#include "shellcode.h" + +const char testname[] = "Executable stack "; + +void doit( void ) +{ + char buf[8192]; + fptr func; + + copy_shellcode(buf, SHELLCODE_RETURN); + + /* Convert the pointer to a function pointer */ + func = (fptr)buf; + + /* Call the code in the buffer */ + func(); + + /* It worked when the function returns */ + itworked(); +} diff --git a/default/paxtest/genpaxtest b/default/paxtest/genpaxtest new file mode 100644 index 0000000..5a22e15 --- /dev/null +++ b/default/paxtest/genpaxtest @@ -0,0 +1,74 @@ +#!/bin/sh +# +# Script to run all the PaX memory protection tests +# +# Copyright(c) 2003,2004 by Peter Busser <peter@xxxxxxxxxxxxx> +# This file has been released under the GNU Public Licence version 2 or later. +# See the file COPYING for details. +# + +echo $RUNDIR +if [ "${RUNDIR}" = "" ] +then + RUNDIR=. +fi + +cat << __here__ > paxtest +#!/bin/sh + +if [ \$# = 1 ] +then + if [ "\$1" = "kiddie" ] + then + PAXTEST_MODE=0 + elif [ "\$1" = "blackhat" ] + then + PAXTEST_MODE=1 + else + echo "usage: paxtest [kiddie|blackhat]" + exit 1 + fi +else + echo "usage: paxtest [kiddie|blackhat]" + exit 1 +fi + +export PAXTEST_MODE + +if [ "\${LD_LIBRARY_PATH}" = "" ] +then + LD_LIBRARY_PATH=${RUNDIR} +else + LD_LIBRARY_PATH=\${LD_LIBRARY_PATH}:${RUNDIR} +fi +export LD_LIBRARY_PATH + +cat <<__end__ | tee paxtest.log +PaXtest - Copyright(c) 2003,2004 by Peter Busser <peter@xxxxxxxxxxxxx> +Released under the GNU Public Licence version 2 or later + +__end__ + +echo "Mode: \$1" >>paxtest.log +uname -a >>paxtest.log +echo >>paxtest.log + +echo 'Writing output to paxtest.log' +echo 'It may take a while for the tests to complete' + +for i in $* +do + ${RUNDIR}/\$i +done >>paxtest.log 2>&1 + +echo "Test results:" +cat paxtest.log + +echo + +__here__ + +chmod 755 paxtest + +exit 0 + diff --git a/default/paxtest/getamap.c b/default/paxtest/getamap.c new file mode 100644 index 0000000..2595df5 --- /dev/null +++ b/default/paxtest/getamap.c @@ -0,0 +1,30 @@ +/* getamap.c - Get the address of the first anonymous mapping + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/mman.h> + + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + +int main( int argc, char *argv[] ) +{ + char *buf; + + buf = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if( buf == MAP_FAILED ) { + fprintf( stderr, "mmap() returned NULL\n" ); + exit( 1 ); + } + + printf( "%p\n", buf ); + + exit( 0 ); +} diff --git a/default/paxtest/getheap.c b/default/paxtest/getheap.c new file mode 100644 index 0000000..2f2372c --- /dev/null +++ b/default/paxtest/getheap.c @@ -0,0 +1,24 @@ +/* getheap.c - Get the address of the first element allocated on the heap and + * print it. + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <stdlib.h> + +int main( int argc, char *argv[] ) +{ + char *p; + + p = malloc( 100 ); + if( p == NULL ) { + perror( "getheap" ); + exit( 1 ); + } + + printf( "%p\n", p ); + + exit( 0 ); +} diff --git a/default/paxtest/getmain.c b/default/paxtest/getmain.c new file mode 100644 index 0000000..0ff2373 --- /dev/null +++ b/default/paxtest/getmain.c @@ -0,0 +1,19 @@ +/* getmain.c - Get the address of the main function and print it + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <stdlib.h> + +void foo(void) +{ + printf( "%p\n", __builtin_return_address(0) ); +} + +int main( int argc, char *argv[] ) +{ + foo(); + exit(0); +} diff --git a/default/paxtest/getshlib.c b/default/paxtest/getshlib.c new file mode 100644 index 0000000..1befcb0 --- /dev/null +++ b/default/paxtest/getshlib.c @@ -0,0 +1,36 @@ +/* getshlib.c - Get the address of a function in a shared library and print it + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <dlfcn.h> + +/* OpenBSD 3.5 doesn't define RTLD_DEFAULT */ +/* OpenBSD 3.6 does but it doesn't actually handle (segfaults on) RTLD_DEFAULT, sigh... */ +#ifdef __OpenBSD__ +#undef RTLD_DEFAULT +#define RTLD_DEFAULT "libc.so" +#endif + +int main( int argc, char *argv[] ) +{ + void *handle; + + handle = dlopen( RTLD_DEFAULT, RTLD_LAZY ); + if( handle != NULL ) { + void *sprintf; + + dlerror(); /* clear any errors */ + sprintf = dlsym( handle, "sprintf" ); + + if( dlerror() == NULL ) { + printf( "%p\n", sprintf ); + } + + dlclose( handle ); + } +} diff --git a/default/paxtest/getstack.c b/default/paxtest/getstack.c new file mode 100644 index 0000000..44b4106 --- /dev/null +++ b/default/paxtest/getstack.c @@ -0,0 +1,18 @@ +/* getstack.c - Get the location of the stack and print it + * (Idea by Peter Roozemaal) + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <stdlib.h> + +int main( int argc, char *argv[] ){ + char a; + + printf( "%p\n", &a ); + + exit( 0 ); +} + diff --git a/default/paxtest/interp.c b/default/paxtest/interp.c new file mode 100644 index 0000000..e7ce97b --- /dev/null +++ b/default/paxtest/interp.c @@ -0,0 +1,5 @@ +#ifdef __UCLIBC__ +const char __invoke_dynamic_linker__[] __attribute__ ((section (".interp"))) = "/lib/ld-uClibc.so.0"; +#else +const char __invoke_dynamic_linker__[] __attribute__ ((section (".interp"))) = "/lib/ld-linux.so.2"; +#endif diff --git a/default/paxtest/mprotanon.c b/default/paxtest/mprotanon.c new file mode 100644 index 0000000..84a4099 --- /dev/null +++ b/default/paxtest/mprotanon.c @@ -0,0 +1,65 @@ +/* mprotanon.c - Tests whether code can be executed in anonymous mappings + * after trying to use mprotect() to make it executable. + * + * Copyright (c)2003,2004 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/mman.h> +#include "body.h" +#include "shellcode.h" + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + +const char testname[] = "Executable anonymous mapping (mprotect) "; + +void doit( void ) +{ + char *buf; + fptr func; + + buf = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if( buf == MAP_FAILED ) { + fprintf( stderr, "mmap() returned NULL\n" ); + exit( 1 ); + } + + copy_shellcode(buf, SHELLCODE_RETURN); + + /* Convert the pointer to a function pointer */ + func = (fptr)buf; + + /* Try to make the anonymous mapping executable first by using + * mprotect. + * + * Some people like to disable this call to make the results look + * better for their system. + * + * The whole purpose of this call is to figure out how the system + * handles mprotect() calls. If it allows the application to use + * mprotect() to override kernel settings, then that is something + * the user of this test suite may like to know. + * + * And yes, I know that this is how UNIX is supposed to work and that + * it is a design decision to allow this override. All the more reason + * to be honest and open about it and to tell the user why (s)he has + * to trade in a bit of security for compatibility. + * + * But then, it is of course easier to simply disable this mprotect() + * call than to fix your kernel and userland. + */ + /* Due to a FreeBSD bug PROT_READ is required */ + do_mprotect( buf, 4096, PROT_READ|PROT_EXEC ); + + /* Call the code in the buffer */ + func(); + + /* It worked when the function returns */ + itworked(); +} diff --git a/default/paxtest/mprotbss.c b/default/paxtest/mprotbss.c new file mode 100644 index 0000000..8a1e3b4 --- /dev/null +++ b/default/paxtest/mprotbss.c @@ -0,0 +1,39 @@ +/* mprotbss.c - Tests whether code in the .bss segment can be executed after + * trying to use mprotect() to make it executable + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/mman.h> +#include "body.h" +#include "shellcode.h" + +const char testname[] = "Executable bss (mprotect) "; + +char buf[MAX_SHELLCODE_LEN]; + +void doit( void ) +{ + fptr func; + + copy_shellcode(buf, SHELLCODE_RETURN); + + /* Convert the pointer to a function pointer */ + func = (fptr)&buf; + + /* Try to make the bss executable first by using mprotect */ + /* Due to a FreeBSD bug PROT_READ is required */ + do_mprotect( &buf, sizeof(buf), PROT_READ|PROT_EXEC ); + + /* Call the code in the buffer */ + func(); + + do_mprotect( &buf, sizeof(buf), PROT_READ|PROT_WRITE ); + + /* It worked when the function returns */ + itworked(); +} diff --git a/default/paxtest/mprotdata.c b/default/paxtest/mprotdata.c new file mode 100644 index 0000000..cad600a --- /dev/null +++ b/default/paxtest/mprotdata.c @@ -0,0 +1,39 @@ +/* mprotdata.c - Tests whether code in the .data segment can be executed after + * trying to use mprotect() to make it executable. + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/mman.h> +#include "body.h" +#include "shellcode.h" + +const char testname[] = "Executable data (mprotect) "; + +char buf[MAX_SHELLCODE_LEN] = SHELLCODE_RETURN_ARRAY; + +void doit( void ) +{ + fptr func; + + copy_shellcode(buf, SHELLCODE_RETURN); + + /* Convert the pointer to a function pointer */ + func = (fptr)&buf; + + /* Try to make the data executable first by using mprotect */ + /* Due to an OpenBSD bug PROT_READ is required */ + do_mprotect( &buf, sizeof(buf), PROT_READ|PROT_EXEC ); + + /* Call the code in the buffer */ + func(); + + do_mprotect( &buf, sizeof(buf), PROT_READ|PROT_WRITE ); + + /* It worked when the function returns */ + itworked(); +} diff --git a/default/paxtest/mprotheap.c b/default/paxtest/mprotheap.c new file mode 100644 index 0000000..e3a56b2 --- /dev/null +++ b/default/paxtest/mprotheap.c @@ -0,0 +1,44 @@ +/* mprotheap.c - Tests whether code on the heap can be executed after trying to + * use mprotect() to make it executable. + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/mman.h> +#include "body.h" +#include "shellcode.h" + +const char testname[] = "Executable heap (mprotect) "; + +void doit( void ) +{ + char *buf; + fptr func; + + buf = malloc( MAX_SHELLCODE_LEN ); + if( buf == NULL ) { + fprintf( stderr, "Out of memory\n" ); + exit( 1 ); + } + + copy_shellcode(buf, SHELLCODE_RETURN); + + /* Try to make the buffer executable by using mprotect() */ + /* Due to a FreeBSD bug PROT_READ is required */ + do_mprotect( buf, SIZE_OF_SHELLCODE_RETURN, PROT_READ|PROT_EXEC ); + + /* Convert the pointer to a function pointer */ + func = (fptr)buf; + + /* Call the code in the buffer */ + func(); + + do_mprotect( buf, MAX_SHELLCODE_LEN, PROT_READ|PROT_WRITE ); + + /* It worked when the function returns */ + itworked(); +} diff --git a/default/paxtest/mprotshbss.c b/default/paxtest/mprotshbss.c new file mode 100644 index 0000000..15a1dbb --- /dev/null +++ b/default/paxtest/mprotshbss.c @@ -0,0 +1,71 @@ +/* mprotshbss.c - Tests whether code in the .bss segment of a shared library can + * be executed after trying to use mprotect() to make it + * executable. + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <dlfcn.h> +#include <sys/mman.h> +#include "body.h" +#include "shellcode.h" + +const char testname[] = "Executable shared library bss (mprotect) "; + +void doit( void ) +{ + char *shbss; + char *shbss2; + fptr func; + void *handle1, *handle2; + + handle1 = dlopen( "shlibtest.so", RTLD_LAZY ); + if( handle1 == NULL ) { + fprintf( stderr, "dlopen() returned NULL\n" ); + exit( 1 ); + } + dlerror(); /* clear any errors */ + shbss = dlsym( handle1, "shbss" ); + if( dlerror() != NULL ) { + fprintf( stderr, "symbol %s not found in %s\n", "shbss", "shlibtest.so" ); + exit( 1 ); + } + + handle2 = dlopen( "shlibtest2.so", RTLD_LAZY ); + if( handle2 == NULL ) { + fprintf( stderr, "dlopen() returned NULL\n" ); + exit( 1 ); + } + dlerror(); /* clear any errors */ + shbss2 = dlsym( handle2, "shbss2" ); + if( dlerror() != NULL ) { + fprintf( stderr, "symbol %s not found in %s\n", "shbss2", "shlibtest2.so" ); + exit( 1 ); + } + + copy_shellcode(shbss, SHELLCODE_RETURN); + copy_shellcode(shbss2, SHELLCODE_RETURN); + + /* Convert the pointer to a function pointer */ + func = shbss < shbss2 ? (fptr)shbss : (fptr)shbss2; + + /* Try to make the memory region executable by using mprotect() */ + /* Due to an OpenBSD bug PROT_READ is required */ + do_mprotect(func, MAX_SHELLCODE_LEN, PROT_READ|PROT_EXEC ); + + /* Call the code in the buffer */ + func(); + + do_mprotect(func, MAX_SHELLCODE_LEN, PROT_READ|PROT_WRITE ); + + /* It worked when the function returns */ + itworked(); + + dlclose( handle1 ); + dlclose( handle2 ); +} diff --git a/default/paxtest/mprotshdata.c b/default/paxtest/mprotshdata.c new file mode 100644 index 0000000..5a4e56c --- /dev/null +++ b/default/paxtest/mprotshdata.c @@ -0,0 +1,71 @@ +/* mprotshdata.c - Tests whether code in the .data segment of a shared library + * can be executed after trying to use mprotect() to make it + * executable. + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <dlfcn.h> +#include <sys/mman.h> +#include "body.h" +#include "shellcode.h" + +const char testname[] = "Executable shared library data (mprotect)"; + +void doit( void ) +{ + fptr func; + char *shdata, *shdata2; + void *handle1, *handle2; + + handle1 = dlopen( "shlibtest.so", RTLD_LAZY ); + if( handle1 == NULL ) { + fprintf( stderr, "dlopen() returned NULL\n" ); + exit( 1 ); + } + dlerror(); /* clear any errors */ + shdata = dlsym( handle1, "shdata" ); + if( dlerror() != NULL ) { + fprintf( stderr, "symbol %s not found in %s\n", "shdata", "shlibtest.so" ); + exit( 1 ); + } + + handle2 = dlopen( "shlibtest2.so", RTLD_LAZY ); + if( handle2 == NULL ) { + fprintf( stderr, "dlopen() returned NULL\n" ); + exit( 1 ); + } + dlerror(); /* clear any errors */ + shdata2 = dlsym( handle2, "shdata2" ); + if( dlerror() != NULL ) { + fprintf( stderr, "symbol %s not found in %s\n", "shdata2", "shlibtest2.so" ); + exit( 1 ); + } + + copy_shellcode(shdata, SHELLCODE_RETURN); + copy_shellcode(shdata2, SHELLCODE_RETURN); + + /* Convert the pointer to a function pointer */ + func = shdata < shdata2 ? (fptr)shdata : (fptr)shdata2; + + /* Try to make the memory region executable by using mprotect() */ + /* Due to an OpenBSD bug PROT_READ is required */ + do_mprotect( func, MAX_SHELLCODE_LEN, PROT_READ|PROT_EXEC ); + + /* Call the code in the buffer */ + func(); + + do_mprotect( func, MAX_SHELLCODE_LEN, PROT_READ|PROT_WRITE ); + + /* It worked when the function returns */ + itworked(); + + dlclose( handle1 ); + dlclose( handle2 ); +} + diff --git a/default/paxtest/mprotstack.c b/default/paxtest/mprotstack.c new file mode 100644 index 0000000..b5f8fe9 --- /dev/null +++ b/default/paxtest/mprotstack.c @@ -0,0 +1,35 @@ +/* mprotstack.c - Tests whether code on the stack can be executed after trying + * to make it executable by using mprotect(). + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/mman.h> +#include "body.h" +#include "shellcode.h" + +const char testname[] = "Executable stack (mprotect) "; + +void doit( void ) +{ + char buf[MAX_SHELLCODE_LEN]; + fptr func; + + copy_shellcode(buf, SHELLCODE_RETURN); + + /* Convert the pointer to a function pointer */ + func = (fptr)&buf; + + /* Try to make the stack executable first */ + do_mprotect( &buf, sizeof(buf), PROT_READ|PROT_WRITE|PROT_EXEC ); + + /* Call the code in the buffer */ + func(); + + /* It worked when the function returns */ + itworked(); +} diff --git a/default/paxtest/randamap.c b/default/paxtest/randamap.c new file mode 100644 index 0000000..96f38b6 --- /dev/null +++ b/default/paxtest/randamap.c @@ -0,0 +1,12 @@ +/* randamap.c - Tests the randomisation of anonymous mappings. + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#ifndef RUNDIR +#error RUNDIR not defined +#endif + +const char testname[] = "Anonymous mapping randomisation test "; +const char testprog[] = RUNDIR"/getamap"; diff --git a/default/paxtest/randbody.c b/default/paxtest/randbody.c new file mode 100644 index 0000000..bd78f12 --- /dev/null +++ b/default/paxtest/randbody.c @@ -0,0 +1,63 @@ +/* randbody.c - This part is shared by the randomisation tests + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <stdlib.h> + +#define COUNT (25) + +extern const char testname[]; +extern const char testprog[]; + +int main( int argc, char *argv[] ) +{ + FILE *fp; + int i; + unsigned long tmp; + unsigned long and; + unsigned long or; + int bits; + int ret; + + printf( "%s: ", testname ); + + and = ~0L; + or = 0L; + for( i = 0; i < COUNT; i++ ) { + fp = popen( testprog, "r" ); + if( fp == NULL ) { + perror( testprog ); + exit( 1 ); + } + + ret = fscanf( fp, "%lx", &tmp ); + if (ret != 1) { + perror ( testprog ); + exit( 1 ); + } + and &= tmp; + or |= tmp; + + pclose( fp ); + } + + if( and == or ) { + printf( "No randomisation\n" ); + } else { + tmp = and ^ ~or; + tmp = or & ~tmp; + bits = 0; + while( tmp != 0 ) { + bits += (tmp%2); + tmp >>= 1; + } + + printf( "%d bits (guessed)\n", bits ); + } + + exit( 0 ); +} + diff --git a/default/paxtest/randheap1.c b/default/paxtest/randheap1.c new file mode 100644 index 0000000..a7e2d2c --- /dev/null +++ b/default/paxtest/randheap1.c @@ -0,0 +1,12 @@ +/* randheap1.c - Tests the randomisation of the heap of ET_EXEC main executable. + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#ifndef RUNDIR +#error RUNDIR not defined +#endif + +const char testname[] = "Heap randomisation test (ET_EXEC) "; +const char testprog[] = RUNDIR"/getheap1"; diff --git a/default/paxtest/randheap2.c b/default/paxtest/randheap2.c new file mode 100644 index 0000000..13e4fb8 --- /dev/null +++ b/default/paxtest/randheap2.c @@ -0,0 +1,12 @@ +/* randheap2.c - Tests the randomisation of the heap of PIE main executable. + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#ifndef RUNDIR +#error RUNDIR not defined +#endif + +const char testname[] = "Heap randomisation test (PIE) "; +const char testprog[] = RUNDIR"/getheap2"; diff --git a/default/paxtest/randmain1.c b/default/paxtest/randmain1.c new file mode 100644 index 0000000..dd7c914 --- /dev/null +++ b/default/paxtest/randmain1.c @@ -0,0 +1,12 @@ +/* randmain1.c - Tests the randomisation of ET_EXEC main executable + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#ifndef RUNDIR +#error RUNDIR not defined +#endif + +const char testname[] = "Main executable randomisation (ET_EXEC) "; +const char testprog[] = RUNDIR"/getmain1"; diff --git a/default/paxtest/randmain2.c b/default/paxtest/randmain2.c new file mode 100644 index 0000000..6f3a85b --- /dev/null +++ b/default/paxtest/randmain2.c @@ -0,0 +1,12 @@ +/* randmain2.c - Tests the randomisation of the ET_DYN main executable + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#ifndef RUNDIR +#error RUNDIR not defined +#endif + +const char testname[] = "Main executable randomisation (PIE) "; +const char testprog[] = RUNDIR"/getmain2"; diff --git a/default/paxtest/randshlib.c b/default/paxtest/randshlib.c new file mode 100644 index 0000000..8a6f52f --- /dev/null +++ b/default/paxtest/randshlib.c @@ -0,0 +1,12 @@ +/* randshlib.c - Tests the randomisation of shared library loading + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#ifndef RUNDIR +#error RUNDIR not defined +#endif + +const char testname[] = "Shared library randomisation test "; +const char testprog[] = RUNDIR"/getshlib"; diff --git a/default/paxtest/randstack1.c b/default/paxtest/randstack1.c new file mode 100644 index 0000000..9efe223 --- /dev/null +++ b/default/paxtest/randstack1.c @@ -0,0 +1,12 @@ +/* randstack.c - Tests the randomisation of the stack pointer. + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#ifndef RUNDIR +#error RUNDIR not defined +#endif + +const char testname[] = "Stack randomisation test (SEGMEXEC) "; +const char testprog[] = RUNDIR"/getstack1"; diff --git a/default/paxtest/randstack2.c b/default/paxtest/randstack2.c new file mode 100644 index 0000000..78f1719 --- /dev/null +++ b/default/paxtest/randstack2.c @@ -0,0 +1,12 @@ +/* randstack.c - Tests the randomisation of the stack pointer. + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#ifndef RUNDIR +#error RUNDIR not defined +#endif + +const char testname[] = "Stack randomisation test (PAGEEXEC) "; +const char testprog[] = RUNDIR"/getstack2"; diff --git a/default/paxtest/results/Adamantix.blackhat b/default/paxtest/results/Adamantix.blackhat new file mode 100644 index 0000000..b0ac914 --- /dev/null +++ b/default/paxtest/results/Adamantix.blackhat @@ -0,0 +1,33 @@ +PaXtest - Copyright(c) 2003,2004 by Peter Busser <peter@xxxxxxxxxxxxx> +Released under the GNU Public Licence version 2 or later + +Mode: blackhat +Linux devbox 2.4.22-1-k7-sec #1 Mon Jan 26 02:12:39 CET 2004 i686 unknown + +Executable anonymous mapping : Killed +Executable bss : Killed +Executable data : Killed +Executable heap : Killed +Executable stack : Killed +Executable anonymous mapping (mprotect) : Killed +Executable bss (mprotect) : Killed +Executable data (mprotect) : Killed +Executable heap (mprotect) : Killed +Executable shared library bss (mprotect) : Killed +Executable shared library data (mprotect): Killed +Executable stack (mprotect) : Killed +Anonymous mapping randomisation test : 16 bits (guessed) +Heap randomisation test (ET_EXEC) : 25 bits (guessed) +Heap randomisation test (ET_DYN) : 25 bits (guessed) +Main executable randomisation (ET_EXEC) : No randomisation +Main executable randomisation (ET_DYN) : 17 bits (guessed) +Shared library randomisation test : 16 bits (guessed) +Stack randomisation test (SEGMEXEC) : 23 bits (guessed) +Stack randomisation test (PAGEEXEC) : 24 bits (guessed) +Return to function (strcpy) : Vulnerable +Return to function (strcpy, RANDEXEC) : Vulnerable +Return to function (memcpy) : Vulnerable +Return to function (memcpy, RANDEXEC) : Vulnerable +Executable shared library bss : Killed +Executable shared library data : Killed +Writable text segments : Killed diff --git a/default/paxtest/results/Adamantix.kiddie b/default/paxtest/results/Adamantix.kiddie new file mode 100644 index 0000000..4507023 --- /dev/null +++ b/default/paxtest/results/Adamantix.kiddie @@ -0,0 +1,33 @@ +PaXtest - Copyright(c) 2003,2004 by Peter Busser <peter@xxxxxxxxxxxxx> +Released under the GNU Public Licence version 2 or later + +Mode: kiddie +Linux devbox 2.4.22-1-k7-sec #1 Mon Jan 26 02:12:39 CET 2004 i686 unknown + +Executable anonymous mapping : Killed +Executable bss : Killed +Executable data : Killed +Executable heap : Killed +Executable stack : Killed +Executable anonymous mapping (mprotect) : Killed +Executable bss (mprotect) : Killed +Executable data (mprotect) : Killed +Executable heap (mprotect) : Killed +Executable shared library bss (mprotect) : Killed +Executable shared library data (mprotect): Killed +Executable stack (mprotect) : Killed +Anonymous mapping randomisation test : 16 bits (guessed) +Heap randomisation test (ET_EXEC) : 25 bits (guessed) +Heap randomisation test (ET_DYN) : 25 bits (guessed) +Main executable randomisation (ET_EXEC) : No randomisation +Main executable randomisation (ET_DYN) : 17 bits (guessed) +Shared library randomisation test : 16 bits (guessed) +Stack randomisation test (SEGMEXEC) : 23 bits (guessed) +Stack randomisation test (PAGEEXEC) : 24 bits (guessed) +Return to function (strcpy) : Vulnerable +Return to function (strcpy, RANDEXEC) : Vulnerable +Return to function (memcpy) : Vulnerable +Return to function (memcpy, RANDEXEC) : Vulnerable +Executable shared library bss : Killed +Executable shared library data : Killed +Writable text segments : Killed diff --git a/default/paxtest/results/Gentoo.blackhat b/default/paxtest/results/Gentoo.blackhat new file mode 100644 index 0000000..98a01a9 --- /dev/null +++ b/default/paxtest/results/Gentoo.blackhat @@ -0,0 +1,33 @@ +PaXtest - Copyright(c) 2003,2004 by Peter Busser <peter@xxxxxxxxxxxxx> +Released under the GNU Public Licence version 2 or later + +Mode: blackhat +Linux simple 2.4.24-grsec-1.9.13 #3 Wed Jan 14 00:48:25 EST 2004 i686 Intel(R) Pentium(R) 4 CPU 1400MHz GenuineIntel GNU/Linux + +Executable anonymous mapping : Killed +Executable bss : Killed +Executable data : Killed +Executable heap : Killed +Executable stack : Killed +Executable anonymous mapping (mprotect) : Killed +Executable bss (mprotect) : Killed +Executable data (mprotect) : Killed +Executable heap (mprotect) : Killed +Executable stack (mprotect) : Killed +Executable shared library bss (mprotect) : Killed +Executable shared library data (mprotect): Killed +Writable text segments : Killed +Anonymous mapping randomisation test : 16 bits (guessed) +Heap randomisation test (ET_EXEC) : 13 bits (guessed) +Heap randomisation test (ET_DYN) : 25 bits (guessed) +Main executable randomisation (ET_EXEC) : 16 bits (guessed) +Main executable randomisation (ET_DYN) : 17 bits (guessed) +Shared library randomisation test : 16 bits (guessed) +Stack randomisation test (SEGMEXEC) : 23 bits (guessed) +Stack randomisation test (PAGEEXEC) : 24 bits (guessed) +Return to function (strcpy) : Vulnerable +Return to function (memcpy) : Vulnerable +Return to function (strcpy, RANDEXEC) : Killed +Return to function (memcpy, RANDEXEC) : Killed +Executable shared library bss : Killed +Executable shared library data : Killed diff --git a/default/paxtest/results/Results.README b/default/paxtest/results/Results.README new file mode 100644 index 0000000..761cd87 --- /dev/null +++ b/default/paxtest/results/Results.README @@ -0,0 +1,10 @@ +The Adamantix paxtest results are generated by running paxtest on a default +kernel configuration. The Adamantix default configuration does not enable +randomisation of normal executables (the so called ET_EXEC files), because +it costs performance and there are only a few executables of this type anyway. + +The Gentoo results show what is possible when a kernel is configured by hand +and all PaX features are enabled (there is no default kernel configuration in +Gentoo, or so the Gentoo developers say). It includes ET_EXEC randomisation, +which also prevents certain return to function attacks. + diff --git a/default/paxtest/rettofunc1.c b/default/paxtest/rettofunc1.c new file mode 100644 index 0000000..de2df25 --- /dev/null +++ b/default/paxtest/rettofunc1.c @@ -0,0 +1,31 @@ +/* rettofunc1.c - Tests whether return to function exploits work or not. + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "body.h" + +const char testname[] = "Return to function (strcpy) "; + +fptr overflow[32] = { + itworked, itworked, itworked, itworked, itworked, itworked, itworked, itworked, + itworked, itworked, itworked, itworked, itworked, itworked, itworked, itworked, + itworked, itworked, itworked, itworked, itworked, itworked, itworked, itworked, + itworked, itworked, itworked, itworked, itworked, itworked, itworked, NULL +}; + +void doit( void ) +{ + char buf[4]; + + if (strlen((const char *)overflow) > sizeof(overflow[0])) { + strcpy( buf, (const char *)overflow ); + } else { + fprintf( stderr, "paxtest: return address contains a NULL byte.\n" ); + exit(1); + } +} diff --git a/default/paxtest/rettofunc1x.c b/default/paxtest/rettofunc1x.c new file mode 100644 index 0000000..e478d28 --- /dev/null +++ b/default/paxtest/rettofunc1x.c @@ -0,0 +1,31 @@ +/* rettofunc1.c - Tests whether return to function exploits work or not. + * + * Copyright (c)2003,2004 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "body.h" + +const char testname[] = "Return to function (strcpy, PIE) "; + +fptr overflow[32] = { + itworked, itworked, itworked, itworked, itworked, itworked, itworked, itworked, + itworked, itworked, itworked, itworked, itworked, itworked, itworked, itworked, + itworked, itworked, itworked, itworked, itworked, itworked, itworked, itworked, + itworked, itworked, itworked, itworked, itworked, itworked, itworked, NULL +}; + +void doit( void ) +{ + char buf[4]; + + if (strlen((const char *)overflow) > sizeof(overflow[0])) { + strcpy( buf, (const char *)overflow ); + } else { + fprintf( stderr, "paxtest: return address contains a NULL byte.\n" ); + exit(1); + } +} diff --git a/default/paxtest/rettofunc2.c b/default/paxtest/rettofunc2.c new file mode 100644 index 0000000..797956d --- /dev/null +++ b/default/paxtest/rettofunc2.c @@ -0,0 +1,25 @@ +/* rettofunc2.c - Tests whether return to function exploits using memcpy() work + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <string.h> +#include "body.h" + +const char testname[] = "Return to function (memcpy) "; + +fptr overflow[32] = { + itworked, itworked, itworked, itworked, itworked, itworked, itworked, itworked, + itworked, itworked, itworked, itworked, itworked, itworked, itworked, itworked, + itworked, itworked, itworked, itworked, itworked, itworked, itworked, itworked, + itworked, itworked, itworked, itworked, itworked, itworked, itworked, itworked +}; + +void doit( void ) +{ + char buf[4]; + + memcpy( buf, overflow, sizeof( overflow ) ); +} diff --git a/default/paxtest/rettofunc2x.c b/default/paxtest/rettofunc2x.c new file mode 100644 index 0000000..17af284 --- /dev/null +++ b/default/paxtest/rettofunc2x.c @@ -0,0 +1,25 @@ +/* rettofunc2.c - Tests whether return to function exploits using memcpy() work + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <string.h> +#include "body.h" + +const char testname[] = "Return to function (memcpy, PIE) "; + +fptr overflow[32] = { + itworked, itworked, itworked, itworked, itworked, itworked, itworked, itworked, + itworked, itworked, itworked, itworked, itworked, itworked, itworked, itworked, + itworked, itworked, itworked, itworked, itworked, itworked, itworked, itworked, + itworked, itworked, itworked, itworked, itworked, itworked, itworked, itworked +}; + +void doit( void ) +{ + char buf[4]; + + memcpy( buf, overflow, sizeof( overflow ) ); +} diff --git a/default/paxtest/runtest.sh b/default/paxtest/runtest.sh new file mode 100755 index 0000000..0014e78 --- /dev/null +++ b/default/paxtest/runtest.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +# Build. +make linux >/dev/null 2>/dev/null +if [ ! -f ./paxtest ]; then + echo "Something went wrong during paxtest build." + exit -1 +fi + +# Run tests +./paxtest blackhat > results.txt + +# Parse results +## TODO + + +# Clean up. +rm -f core.* + +rm -f results.txt diff --git a/default/paxtest/shellcode.h b/default/paxtest/shellcode.h new file mode 100644 index 0000000..069a0f7 --- /dev/null +++ b/default/paxtest/shellcode.h @@ -0,0 +1,37 @@ +#include <unistd.h> +#include <string.h> + +#define MAX_SHELLCODE_LEN 12 + +#if defined(__powerpc__) +#define SHELLCODE_RETURN_ARRAY { '\x4e', '\x80', '\x00', '\x20' } +#define SHELLCODE_RETURN "\x4e\x80\x00\x20" +#define SIZE_OF_SHELLCODE_RETURN 4 +#elif defined(__sparc__) && !defined(__arch64__) +#define SHELLCODE_RETURN_ARRAY { '\x81', '\xc7', '\xe0', '\x08', '\x81', '\xe8' ,'\x00', '\x00' } +#define SHELLCODE_RETURN "\x81\xc7\xe0\x08\x81\xe8\x00\x00" +#define SIZE_OF_SHELLCODE_RETURN 8 +#elif defined(__sparc__) && defined(__arch64__) +#define SHELLCODE_RETURN_ARRAY { '\x9d', '\xe3', '\xbf', '\x40', '\x81', '\xcf', '\xe0', '\x08', '\x01', '\x00', '\x00', '\x00' } +#define SHELLCODE_RETURN "\x9d\xe3\xbf\x40\x81\xcf\xe0\x08\x01\x00\x00\x00" +#define SIZE_OF_SHELLCODE_RETURN 12 +#else +#define SHELLCODE_RETURN_ARRAY { '\xc3' } +#define SHELLCODE_RETURN "\xc3" +#define SIZE_OF_SHELLCODE_RETURN 1 +#endif + +#if defined(__powerpc64__) +static inline void copy_shellcode(char *dest, char *src) +{ + /* 12 bytes total */ + unsigned long dstaddr = (unsigned long)dest + sizeof(dstaddr); + memcpy(dest, &dstaddr, sizeof(dstaddr)); + memcpy(dest + sizeof(dstaddr), src, SIZE_OF_SHELLCODE_RETURN); +} +#else +static inline void copy_shellcode(char *dest, char *src) +{ + memcpy(dest, src, SIZE_OF_SHELLCODE_RETURN); +} +#endif diff --git a/default/paxtest/shlibbss.c b/default/paxtest/shlibbss.c new file mode 100644 index 0000000..8fd2a52 --- /dev/null +++ b/default/paxtest/shlibbss.c @@ -0,0 +1,63 @@ +/* shlibbss.c - Tests whether code in the .bss segment of a shared library can + * be executed + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <dlfcn.h> +#include "body.h" +#include "shellcode.h" + +const char testname[] = "Executable shared library bss "; + +void doit( void ) +{ + char *shbss; + char *shbss2; + fptr func; + void *handle1, *handle2; + + handle1 = dlopen( "shlibtest.so", RTLD_LAZY ); + if( handle1 == NULL ) { + fprintf( stderr, "dlopen() returned NULL\n" ); + exit( 1 ); + } + dlerror(); /* clear any errors */ + shbss = dlsym( handle1, "shbss" ); + if( dlerror() != NULL ) { + fprintf( stderr, "symbol %s not found in %s\n", "shbss", "shlibtest.so" ); + exit( 1 ); + } + + handle2 = dlopen( "shlibtest2.so", RTLD_LAZY ); + if( handle2 == NULL ) { + fprintf( stderr, "dlopen() returned NULL\n" ); + exit( 1 ); + } + dlerror(); /* clear any errors */ + shbss2 = dlsym( handle2, "shbss2" ); + if( dlerror() != NULL ) { + fprintf( stderr, "symbol %s not found in %s\n", "shbss2", "shlibtest2.so" ); + exit( 1 ); + } + + copy_shellcode(shbss, SHELLCODE_RETURN); + copy_shellcode(shbss2, SHELLCODE_RETURN); + + /* Convert the pointer to a function pointer */ + func = shbss < shbss2 ? (fptr)shbss : (fptr)shbss2; + + /* Call the code in the buffer */ + func(); + + /* It worked when the function returns */ + itworked(); + + dlclose( handle1 ); + dlclose( handle2 ); +} diff --git a/default/paxtest/shlibdata.c b/default/paxtest/shlibdata.c new file mode 100644 index 0000000..2e070a6 --- /dev/null +++ b/default/paxtest/shlibdata.c @@ -0,0 +1,63 @@ +/* shlibdata.c - Tests whether code in the .data segment of a shared library can + * be executed + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <dlfcn.h> +#include "body.h" +#include "shellcode.h" + +const char testname[] = "Executable shared library data "; + + +void doit( void ) +{ + fptr func; + char *shdata, *shdata2; + void *handle1, *handle2; + + handle1 = dlopen( "shlibtest.so", RTLD_LAZY ); + if( handle1 == NULL ) { + fprintf( stderr, "dlopen() returned NULL\n" ); + exit( 1 ); + } + dlerror(); /* clear any errors */ + shdata = dlsym( handle1, "shdata" ); + if( dlerror() != NULL ) { + fprintf( stderr, "symbol %s not found in %s\n", "shdata", "shlibtest.so" ); + exit( 1 ); + } + + handle2 = dlopen( "shlibtest2.so", RTLD_LAZY ); + if( handle2 == NULL ) { + fprintf( stderr, "dlopen() returned NULL\n" ); + exit( 1 ); + } + dlerror(); /* clear any errors */ + shdata2 = dlsym( handle2, "shdata2" ); + if( dlerror() != NULL ) { + fprintf( stderr, "symbol %s not found in %s\n", "shdata2", "shlibtest2.so" ); + exit( 1 ); + } + + copy_shellcode(shdata, SHELLCODE_RETURN); + copy_shellcode(shdata2, SHELLCODE_RETURN); + + /* Convert the pointer to a function pointer */ + func = shdata < shdata2 ? (fptr)shdata : (fptr)shdata2; + + /* Call the code in the buffer */ + func(); + + /* It worked when the function returns */ + itworked(); + + dlclose( handle1 ); + dlclose( handle2 ); +} diff --git a/default/paxtest/shlibtest.c b/default/paxtest/shlibtest.c new file mode 100644 index 0000000..c61572e --- /dev/null +++ b/default/paxtest/shlibtest.c @@ -0,0 +1,16 @@ +/* shlibtest.c - Shared library used by the shared library tests. + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ +#include "shellcode.h" + +char shbss[4096]; + +char shdata[4096] = SHELLCODE_RETURN_ARRAY; + +/* A function which does nothing, it only exists so it can be referenced */ +int shlibtest( void ) +{ + return 1; +} diff --git a/default/paxtest/shlibtest2.c b/default/paxtest/shlibtest2.c new file mode 100644 index 0000000..111ea05 --- /dev/null +++ b/default/paxtest/shlibtest2.c @@ -0,0 +1,17 @@ +/* shlibtest2.c - Shared library used by the shared library tests. + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include "shellcode.h" + +char shbss2[4096]; + +char shdata2[4096] = SHELLCODE_RETURN_ARRAY; + +/* A function which does nothing, it only exists so it can be referenced */ +int shlibtest2( void ) +{ + return 1; +} diff --git a/default/paxtest/targets b/default/paxtest/targets new file mode 100644 index 0000000..db9097b --- /dev/null +++ b/default/paxtest/targets @@ -0,0 +1,10 @@ +Choose one of the following make targets: + +linux Linux (gcc default) +linux32 32bit Linux +linux64 64bit Linux + +openbsd OpenBSD + +clean Clean up + diff --git a/default/paxtest/writetext.c b/default/paxtest/writetext.c new file mode 100644 index 0000000..59bc97f --- /dev/null +++ b/default/paxtest/writetext.c @@ -0,0 +1,56 @@ +/* writetext.c - Test whether a .text sections can be written + * + * Copyright (c)2003 by Peter Busser <peter@xxxxxxxxxxxxx> + * This file has been released under the GNU Public Licence version 2 or later + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <signal.h> +#include <sys/mman.h> +#include "body.h" + +const char testname[] = "Writable text segments "; + +extern int shlibtest( void ); + +static void sigsegv( int sig ) +{ + printf( "Killed\n" ); + exit( 1 ); +} + +void doit( void ) +{ + volatile char *buf; + char c; + + buf = (char*)shlibtest; + + signal( SIGSEGV, sigsegv ); + + /* Try to make the text writable first by using mprotect + * + * Some people like to disable this call to make the results look + * better for their system. + * + * The purpose of the mprotect() here is to *really* try to write to + * that piece of executable memory. If you want to know whether a box + * can be opened or not, you try to pull it open. Just looking at it, + * seeing that it is closed, and therefore concluding that it cannot + * be opened is rather lame. + * + * But then, it is of course easier to get good paxtest results by + * disabling this mprotect than to fix your kernel code and userland. + */ + do_mprotect( buf, 4096, PROT_READ|PROT_WRITE|PROT_EXEC ); + + /* Try to write something */ + /* gcc 4.5 optimized this out if buf wasn't volatile */ + *buf = 'X'; + + /* It worked when the function returns */ + itworked(); +} -- To stop receiving notification emails like this one, please contact the administrator of this repository. _______________________________________________ kernel mailing list -- kernel@xxxxxxxxxxxxxxxxxxxxxxx To unsubscribe send an email to kernel-leave@xxxxxxxxxxxxxxxxxxxxxxx