diff options
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 13 | ||||
-rw-r--r-- | libgcc/Makefile.in | 4 | ||||
-rw-r--r-- | libgcc/config.host | 16 | ||||
-rw-r--r-- | libgcc/config/i386/enable-execute-stack-mingw32.c | 38 | ||||
-rw-r--r-- | libgcc/configure | 3 | ||||
-rw-r--r-- | libgcc/configure.ac | 1 | ||||
-rw-r--r-- | libgcc/enable-execute-stack-empty.c | 7 | ||||
-rw-r--r-- | libgcc/enable-execute-stack-mprotect.c | 119 |
8 files changed, 200 insertions, 1 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index c84bb05..75e7ef0 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,16 @@ +2011-06-09 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * enable-execute-stack-empty.c: New file. + * enable-execute-stack-mprotect.c: New file. + * config/i386/enable-execute-stack-mingw32.c: New file. + * config.host (enable_execute_stack): New variable. + Select appropriate variants. + * configure.ac: Link enable-execute-stack.c to + $enable_execute_stack. + * configure: Regenerate. + * Makefile.in (LIB2ADD): Add enable-execute-stack.c. + (lib2funcs): Remove _enable_execute_stack. + 2011-06-09 David S. Miller <davem@davemloft.net> Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in index 4a075ff..383a661 100644 --- a/libgcc/Makefile.in +++ b/libgcc/Makefile.in @@ -313,9 +313,11 @@ ifneq ($(GCC_EXTRA_PARTS),) endif endif +LIB2ADD += enable-execute-stack.c + # Library members defined in libgcc2.c. lib2funcs = _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _cmpdi2 _ucmpdi2 \ - _clear_cache _enable_execute_stack _trampoline __main _absvsi2 \ + _clear_cache _trampoline __main _absvsi2 \ _absvdi2 _addvsi3 _addvdi3 _subvsi3 _subvdi3 _mulvsi3 _mulvdi3 \ _negvsi2 _negvdi2 _ctors _ffssi2 _ffsdi2 _clz _clzsi2 _clzdi2 \ _ctzsi2 _ctzdi2 _popcount_tab _popcountsi2 _popcountdi2 \ diff --git a/libgcc/config.host b/libgcc/config.host index 38b0eb3..c2b5dbc 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -44,6 +44,8 @@ # The default is ".hidden". # cpu_type The name of the cpu, if different from the first # chunk of the canonical host name. +# enable_execute_stack The name of a source file implementing +# __enable_execute_stack. # extra_parts List of extra object files that should be compiled # for this target machine. This may be overridden # by setting EXTRA_PARTS in a tmake_file fragment. @@ -57,6 +59,7 @@ # "$cpu_type/t-$cpu_type". asm_hidden_op=.hidden +enable_execute_stack= extra_parts= tmake_file= md_unwind_header=no-unwind.h @@ -203,6 +206,19 @@ case ${host} in esac case ${host} in +*-*-darwin* | *-*-freebsd* | *-*-netbsd* | *-*-openbsd* | *-*-solaris2* | \ + alpha*-dec-osf5.1*) + enable_execute_stack=enable-execute-stack-mprotect.c + ;; +i[34567]86-*-mingw* | x86_64-*-mingw*) + enable_execute_stack=config/i386/enable-execute-stack-mingw32.c + ;; +*) + enable_execute_stack=enable-execute-stack-empty.c; + ;; +esac + +case ${host} in # Support site-specific machine types. *local*) rest=`echo ${host} | sed -e "s/$cpu_type-//"` diff --git a/libgcc/config/i386/enable-execute-stack-mingw32.c b/libgcc/config/i386/enable-execute-stack-mingw32.c new file mode 100644 index 0000000..8f3d272 --- /dev/null +++ b/libgcc/config/i386/enable-execute-stack-mingw32.c @@ -0,0 +1,38 @@ +/* Implement __enable_execute_stack for Windows32. + Copyright (C) 2011 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC 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. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <windows.h> + +extern void __enable_execute_stack (void *); + +void +__enable_execute_stack (void *addr) +{ + MEMORY_BASIC_INFORMATION b; + + if (!VirtualQuery (addr, &b, sizeof(b))) + abort (); + VirtualProtect (b.BaseAddress, b.RegionSize, PAGE_EXECUTE_READWRITE, + &b.Protect); +} diff --git a/libgcc/configure b/libgcc/configure index 1a3a0bd..1351022 100644 --- a/libgcc/configure +++ b/libgcc/configure @@ -3962,6 +3962,8 @@ tmake_file="${tmake_file_}" +ac_config_links="$ac_config_links enable-execute-stack.c:$enable_execute_stack" + ac_config_links="$ac_config_links md-unwind-support.h:config/$md_unwind_header" @@ -4689,6 +4691,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 for ac_config_target in $ac_config_targets do case $ac_config_target in + "enable-execute-stack.c") CONFIG_LINKS="$CONFIG_LINKS enable-execute-stack.c:$enable_execute_stack" ;; "md-unwind-support.h") CONFIG_LINKS="$CONFIG_LINKS md-unwind-support.h:config/$md_unwind_header" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;; diff --git a/libgcc/configure.ac b/libgcc/configure.ac index f2bcabf..4f56c3b 100644 --- a/libgcc/configure.ac +++ b/libgcc/configure.ac @@ -278,6 +278,7 @@ AC_SUBST(tmake_file) AC_SUBST(cpu_type) AC_SUBST(extra_parts) AC_SUBST(asm_hidden_op) +AC_CONFIG_LINKS([enable-execute-stack.c:$enable_execute_stack]) AC_CONFIG_LINKS([md-unwind-support.h:config/$md_unwind_header]) # We need multilib support. diff --git a/libgcc/enable-execute-stack-empty.c b/libgcc/enable-execute-stack-empty.c new file mode 100644 index 0000000..81786de --- /dev/null +++ b/libgcc/enable-execute-stack-empty.c @@ -0,0 +1,7 @@ +/* Dummy implementation of __enable_execute_stack. */ + +/* Attempt to turn on execute permission for the stack. */ +void +__enable_execute_stack (void *addr __attribute__((__unused__))) +{ +} diff --git a/libgcc/enable-execute-stack-mprotect.c b/libgcc/enable-execute-stack-mprotect.c new file mode 100644 index 0000000..1ad77bd --- /dev/null +++ b/libgcc/enable-execute-stack-mprotect.c @@ -0,0 +1,119 @@ +/* Implement __enable_execute_stack using mprotect(2). + Copyright (C) 2011 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC 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. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <sys/mman.h> +#include <unistd.h> +#include <stdlib.h> + +#define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC) + +static int need_enable_exec_stack; + +static void check_enabling (void) __attribute__ ((unused)); +extern void __enable_execute_stack (void *); + +#if defined __FreeBSD__ +#include <sys/sysctl.h> + +static void __attribute__ ((constructor)) +check_enabling (void) +{ + int prot = 0; + size_t len = sizeof (prot); + + sysctlbyname ("kern.stackprot", &prot, &len, NULL, 0); + if (prot != STACK_PROT_RWX) + need_enable_exec_stack = 1; +} +#elif defined __sun__ && defined __svr4__ +static void __attribute__ ((constructor)) +check_enabling (void) +{ + int prot = (int) sysconf (_SC_STACK_PROT); + + if (prot != STACK_PROT_RWX) + need_enable_exec_stack = 1; +} +#else +/* There is no way to query the execute permission of the stack, so + we always issue the mprotect() call. */ + +static int need_enable_exec_stack = 1; +#endif + +#if defined __NetBSD__ +/* Note that we go out of our way to use namespace-non-invasive calls + here. Unfortunately, there is no libc-internal name for mprotect(). */ + +#include <sys/sysctl.h> + +extern int __sysctl (int *, unsigned int, void *, size_t *, void *, size_t); + +static int +getpagesize (void) +{ + static int size; + + if (size == 0) + { + int mib[2]; + size_t len; + + mib[0] = CTL_HW; + mib[1] = HW_PAGESIZE; + len = sizeof (size); + (void) __sysctl (mib, 2, &size, &len, NULL, 0); + } + return size; +} +#endif /* __NetBSD__ */ + +/* Attempt to turn on access permissions for the stack. Unfortunately it + is not possible to make this namespace-clean.*/ + +void +__enable_execute_stack (void *addr) +{ + if (!need_enable_exec_stack) + return; + else + { + static long size, mask; + + if (size == 0) { + size = getpagesize (); + mask = ~(size - 1); + } + + char *page = (char *) (((long) addr) & mask); + char *end = (char *) + ((((long) (addr + __LIBGCC_TRAMPOLINE_SIZE__)) & mask) + size); + + if (mprotect (page, end - page, STACK_PROT_RWX) < 0) + /* Note that no errors should be emitted by this code; it is + considered dangerous for library calls to send messages to + stdout/stderr. */ + abort (); + } +} |