11debfc3dSmrg /* Implement __enable_execute_stack using mprotect(2).
2*8feb0f0bSmrg Copyright (C) 2011-2020 Free Software Foundation, Inc.
31debfc3dSmrg
41debfc3dSmrg This file is part of GCC.
51debfc3dSmrg
61debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
71debfc3dSmrg the terms of the GNU General Public License as published by the Free
81debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
91debfc3dSmrg version.
101debfc3dSmrg
111debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
121debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
131debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
141debfc3dSmrg for more details.
151debfc3dSmrg
161debfc3dSmrg Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg 3.1, as published by the Free Software Foundation.
191debfc3dSmrg
201debfc3dSmrg You should have received a copy of the GNU General Public License and
211debfc3dSmrg a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
231debfc3dSmrg <http://www.gnu.org/licenses/>. */
241debfc3dSmrg
251debfc3dSmrg #include <sys/mman.h>
261debfc3dSmrg #include <unistd.h>
271debfc3dSmrg #include <stdlib.h>
281debfc3dSmrg
291debfc3dSmrg #define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC)
301debfc3dSmrg
311debfc3dSmrg static int need_enable_exec_stack;
321debfc3dSmrg
331debfc3dSmrg static void check_enabling (void) __attribute__ ((unused));
341debfc3dSmrg extern void __enable_execute_stack (void *);
351debfc3dSmrg
361debfc3dSmrg #if defined __sun__ && defined __svr4__
371debfc3dSmrg static void __attribute__ ((constructor))
check_enabling(void)381debfc3dSmrg check_enabling (void)
391debfc3dSmrg {
401debfc3dSmrg int prot = (int) sysconf (_SC_STACK_PROT);
411debfc3dSmrg
421debfc3dSmrg if (prot != STACK_PROT_RWX)
431debfc3dSmrg need_enable_exec_stack = 1;
441debfc3dSmrg }
451debfc3dSmrg #else
461debfc3dSmrg /* There is no way to query the execute permission of the stack, so
471debfc3dSmrg we always issue the mprotect() call. */
481debfc3dSmrg
491debfc3dSmrg static int need_enable_exec_stack = 1;
501debfc3dSmrg #endif
511debfc3dSmrg
521debfc3dSmrg /* Attempt to turn on access permissions for the stack. Unfortunately it
531debfc3dSmrg is not possible to make this namespace-clean.*/
541debfc3dSmrg
551debfc3dSmrg void
__enable_execute_stack(void * addr)561debfc3dSmrg __enable_execute_stack (void *addr)
571debfc3dSmrg {
581debfc3dSmrg if (!need_enable_exec_stack)
591debfc3dSmrg return;
601debfc3dSmrg else
611debfc3dSmrg {
621debfc3dSmrg static long size, mask;
631debfc3dSmrg
641debfc3dSmrg if (size == 0) {
651debfc3dSmrg size = getpagesize ();
661debfc3dSmrg mask = ~(size - 1);
671debfc3dSmrg }
681debfc3dSmrg
691debfc3dSmrg char *page = (char *) (((long) addr) & mask);
701debfc3dSmrg char *end = (char *)
711debfc3dSmrg ((((long) (addr + __LIBGCC_TRAMPOLINE_SIZE__)) & mask) + size);
721debfc3dSmrg
731debfc3dSmrg if (mprotect (page, end - page, STACK_PROT_RWX) < 0)
741debfc3dSmrg /* Note that no errors should be emitted by this code; it is
751debfc3dSmrg considered dangerous for library calls to send messages to
761debfc3dSmrg stdout/stderr. */
771debfc3dSmrg abort ();
781debfc3dSmrg }
791debfc3dSmrg }
80