diff options
author | Nick Clifton <nickc@redhat.com> | 2022-05-03 11:42:24 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2022-05-03 11:42:24 +0100 |
commit | ba951afb99912da01a6e8434126b8fac7aa75107 (patch) | |
tree | e94ddfba29d29a82ab36d28592d6c8e7edd04350 /ld | |
parent | 46465574a925062ba7dfa72f49ba5199d7a39fc3 (diff) | |
download | gdb-ba951afb99912da01a6e8434126b8fac7aa75107.zip gdb-ba951afb99912da01a6e8434126b8fac7aa75107.tar.gz gdb-ba951afb99912da01a6e8434126b8fac7aa75107.tar.bz2 |
Add a linker warning when creating potentially dangerous executable segments. Add tests, options to disabke and configure switches to choose defaults.
Diffstat (limited to 'ld')
-rw-r--r-- | ld/NEWS | 24 | ||||
-rw-r--r-- | ld/aclocal.m4 | 193 | ||||
-rw-r--r-- | ld/config.in | 12 | ||||
-rwxr-xr-x | ld/configure | 75 | ||||
-rw-r--r-- | ld/configure.ac | 52 | ||||
-rw-r--r-- | ld/emultempl/elf.em | 3 | ||||
-rw-r--r-- | ld/ld.texi | 16 | ||||
-rw-r--r-- | ld/ldlex.h | 5 | ||||
-rw-r--r-- | ld/lexsup.c | 31 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/changelma.d | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/elf.exp | 50 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/flags1.d | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/maxpage5.d | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/note-2.d | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/rwx-segments-1.l | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/rwx-segments-2.l | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/rwx-segments-2.t | 20 |
17 files changed, 370 insertions, 121 deletions
@@ -1,6 +1,6 @@ -*- text -*- -* The linker will now generate a warning message if the stack is made +* The ELF linker will now generate a warning message if the stack is made executable. By default this warning is not issued if the user has specifically requested an executable stack via the "-z execstack" command line option, but the warning can be forced via the new @@ -8,6 +8,28 @@ an executable stack can be suppressed via the "--no-warn-execstack" option. + In addition the ELF linker will also warn if it creates a memory resident + segment with all three of the Read, Write and eXecute permissions set, or + if it creates a thread local data segment with the eXecute permission set. + These warnings can be disabled via --no-warn-rwx-segments option and + re-enabled via the --warn-rwx-segments option. + + New configure options can also control these new features: + + --enable-warn-execstack=no + will disable the warnings about creating an executable stack. + + --enable-warn-execstack=yes + will make --warn-execstack enabled by default. + + --enable-warn-rwx-segments=no + will make --no-warn-rwx-segments enabled by default. + + --enable-defaul-execstack=no + will stop the creation of an executable stack simply because an input file + is missing a .note.GNU-stack section, even on architectures where this + ehaviour is the default. + * TYPE=<type> is now supported in an output section description to set the section type value. diff --git a/ld/aclocal.m4 b/ld/aclocal.m4 index 631ead7..314969c 100644 --- a/ld/aclocal.m4 +++ b/ld/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15.1 -*- Autoconf -*- +# generated automatically by aclocal 1.16.2 -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2017 Free Software Foundation, Inc. +# Copyright (C) 2002-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.]) # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.15' +[am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15.1], [], +m4_if([$1], [1.16.2], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15.1])dnl +[AM_AUTOMAKE_VERSION([1.16.2])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -332,13 +332,12 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. - # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], @@ -346,49 +345,43 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE([$CONFIG_FILES], + [*\'*], [eval set x "$CONFIG_FILES"], + [*], [set x $CONFIG_FILES]) shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME(["$am_mf"])` + am_filepart=`AS_BASENAME(["$am_mf"])` + AM_RUN_LOG([cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles]) || am_rc=$? done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE="gmake" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi + AS_UNSET([am_dirpart]) + AS_UNSET([am_filepart]) + AS_UNSET([am_mf]) + AS_UNSET([am_rc]) + rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS @@ -397,18 +390,17 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) + [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -495,8 +487,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. @@ -563,7 +555,7 @@ END Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: <http://www.gnu.org/software/coreutils/>. +that behaves properly: <https://www.gnu.org/software/coreutils/>. If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -605,7 +597,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -626,7 +618,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 1998-2017 Free Software Foundation, Inc. +# Copyright (C) 1998-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -647,7 +639,7 @@ fi]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -682,7 +674,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -690,49 +682,42 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) # AM_MAKE_INCLUDE() # ----------------- -# Check to see how make treats includes. +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' +[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) + AS_CASE([$?:`cat confinc.out 2>/dev/null`], + ['0:this is the am__doit target'], + [AS_CASE([$s], + [BSD], [am__include='.include' am__quote='"'], + [am__include='include' am__quote=''])]) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT([${_am_result}]) +AC_SUBST([am__include])]) +AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -771,7 +756,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -800,7 +785,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -847,7 +832,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -866,7 +851,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -947,7 +932,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2017 Free Software Foundation, Inc. +# Copyright (C) 2009-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1007,7 +992,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1035,7 +1020,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2017 Free Software Foundation, Inc. +# Copyright (C) 2006-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1054,7 +1039,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2017 Free Software Foundation, Inc. +# Copyright (C) 2004-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/ld/config.in b/ld/config.in index 26d55a0..cc5b476 100644 --- a/ld/config.in +++ b/ld/config.in @@ -16,12 +16,24 @@ /* Define if you want compressed debug sections by default. */ #undef DEFAULT_FLAG_COMPRESS_DEBUG +/* Define to 0 if you want to disable the generation of an executable stack + when a .note-GNU-stack section is missing. */ +#undef DEFAULT_LD_EXECSTACK + /* The default method for DT_TEXTREL check in ELF linker. */ #undef DEFAULT_LD_TEXTREL_CHECK /* Define to 1 if DT_TEXTREL check is warning in ELF linker by default. */ #undef DEFAULT_LD_TEXTREL_CHECK_WARNING +/* Define to 1 if you want to enable --warn-execstack in ELF linker by + default. */ +#undef DEFAULT_LD_WARN_EXECSTACK + +/* Define to 0 if you want to disable --warn-rwx-segments in ELF linker by + default. */ +#undef DEFAULT_LD_WARN_RWX_SEGMENTS + /* Define to 1 if you want to enable -z relro in ELF linker by default. */ #undef DEFAULT_LD_Z_RELRO diff --git a/ld/configure b/ld/configure index bab2d08..b4b0ce1 100755 --- a/ld/configure +++ b/ld/configure @@ -838,6 +838,9 @@ enable_new_dtags enable_relro enable_textrel_check enable_separate_code +enable_warn_execstack +enable_warn_rwx_segments +enable_default_execstack enable_error_handling_script enable_default_hash_style enable_initfini_array @@ -1510,6 +1513,13 @@ Optional Features: --enable-textrel-check=[yes|no|warning|error] enable DT_TEXTREL check in ELF linker --enable-separate-code enable -z separate-code in ELF linker by default + --enable-warn-execstack enable warnings when creating an executable stack + --enable-warn-rwx-segments + enable warnings when creating segements with RWX + permissions + --enable-default-execstack + create an executable stack if an input file is + missing a .note.GNU-stack section --enable-error-handling-script enable/disable support for the --error-handling-script option @@ -11460,7 +11470,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11463 "configure" +#line 11473 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11566,7 +11576,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11569 "configure" +#line 11579 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -15427,6 +15437,38 @@ esac fi + +ac_default_ld_warn_execstack=unset +# Check whether --enable-warn-execstack was given. +if test "${enable_warn_execstack+set}" = set; then : + enableval=$enable_warn_execstack; case "${enableval}" in + yes) ac_default_ld_warn_execstack=1 ;; + no) ac_default_ld_warn_execstack=-1 ;; +esac +fi + + +ac_default_ld_warn_rwx_segments=unset +# Check whether --enable-warn-rwx-segments was given. +if test "${enable_warn_rwx_segments+set}" = set; then : + enableval=$enable_warn_rwx_segments; case "${enableval}" in + yes) ac_default_ld_warn_rwx_segments=1 ;; + no) ac_default_ld_warn_rwx_segments=0 ;; +esac +fi + + +ac_default_ld_default_execstack=unset +# Check whether --enable-default-execstack was given. +if test "${enable_default_execstack+set}" = set; then : + enableval=$enable_default_execstack; case "${enableval}" in + yes) ac_default_ld_default_execstack=1 ;; + no) ac_default_ld_default_execstack=0 ;; +esac +fi + + + # Decide if --error-handling-script should be supported. ac_support_error_handling_script=unset # Check whether --enable-error-handling-script was given. @@ -16954,6 +16996,35 @@ cat >>confdefs.h <<_ACEOF _ACEOF + +if test "${ac_default_ld_warn_execstack}" = unset; then + ac_default_ld_warn_execstack=0 +fi + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_LD_WARN_EXECSTACK $ac_default_ld_warn_execstack +_ACEOF + + +if test "${ac_default_ld_warn_rwx_segments}" = unset; then + ac_default_ld_warn_rwx_segments=1 +fi + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_LD_WARN_RWX_SEGMENTS $ac_default_ld_warn_rwx_segments +_ACEOF + + +if test "${ac_default_ld_default_execstack}" = unset; then + ac_default_ld_default_execstack=1 +fi + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_LD_EXECSTACK $ac_default_ld_default_execstack +_ACEOF + + + if test "${ac_support_error_handling_script}" = unset; then ac_support_error_handling_script=1 fi diff --git a/ld/configure.ac b/ld/configure.ac index 7f4cff0..0b29e81 100644 --- a/ld/configure.ac +++ b/ld/configure.ac @@ -203,6 +203,35 @@ AC_ARG_ENABLE(separate-code, no) ac_default_ld_z_separate_code=0 ;; esac]) + +ac_default_ld_warn_execstack=unset +AC_ARG_ENABLE(warn-execstack, + AS_HELP_STRING([--enable-warn-execstack], + [enable warnings when creating an executable stack]), +[case "${enableval}" in + yes) ac_default_ld_warn_execstack=1 ;; + no) ac_default_ld_warn_execstack=-1 ;; +esac]) + +ac_default_ld_warn_rwx_segments=unset +AC_ARG_ENABLE(warn-rwx-segments, + AS_HELP_STRING([--enable-warn-rwx-segments], + [enable warnings when creating segements with RWX permissions]), +[case "${enableval}" in + yes) ac_default_ld_warn_rwx_segments=1 ;; + no) ac_default_ld_warn_rwx_segments=0 ;; +esac]) + +ac_default_ld_default_execstack=unset +AC_ARG_ENABLE(default-execstack, + AS_HELP_STRING([--enable-default-execstack], + [create an executable stack if an input file is missing a .note.GNU-stack section]), +[case "${enableval}" in + yes) ac_default_ld_default_execstack=1 ;; + no) ac_default_ld_default_execstack=0 ;; +esac]) + + # Decide if --error-handling-script should be supported. ac_support_error_handling_script=unset AC_ARG_ENABLE(error-handling-script, @@ -501,6 +530,29 @@ AC_DEFINE_UNQUOTED(DEFAULT_LD_Z_SEPARATE_CODE, $ac_default_ld_z_separate_code, [Define to 1 if you want to enable -z separate-code in ELF linker by default.]) + +if test "${ac_default_ld_warn_execstack}" = unset; then + ac_default_ld_warn_execstack=0 +fi +AC_DEFINE_UNQUOTED(DEFAULT_LD_WARN_EXECSTACK, + $ac_default_ld_warn_execstack, + [Define to 1 if you want to enable --warn-execstack in ELF linker by default.]) + +if test "${ac_default_ld_warn_rwx_segments}" = unset; then + ac_default_ld_warn_rwx_segments=1 +fi +AC_DEFINE_UNQUOTED(DEFAULT_LD_WARN_RWX_SEGMENTS, + $ac_default_ld_warn_rwx_segments, + [Define to 0 if you want to disable --warn-rwx-segments in ELF linker by default.]) + +if test "${ac_default_ld_default_execstack}" = unset; then + ac_default_ld_default_execstack=1 +fi +AC_DEFINE_UNQUOTED(DEFAULT_LD_EXECSTACK, + $ac_default_ld_default_execstack, + [Define to 0 if you want to disable the generation of an executable stack when a .note-GNU-stack section is missing.]) + + if test "${ac_support_error_handling_script}" = unset; then ac_support_error_handling_script=1 fi diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em index 7ae6f6d..c027559 100644 --- a/ld/emultempl/elf.em +++ b/ld/emultempl/elf.em @@ -92,6 +92,9 @@ EOF fi fragment <<EOF link_info.separate_code = DEFAULT_LD_Z_SEPARATE_CODE; + link_info.warn_execstack = DEFAULT_LD_WARN_EXECSTACK; + link_info.no_warn_rwx_segments = ! DEFAULT_LD_WARN_RWX_SEGMENTS; + link_info.default_execstack = DEFAULT_LD_EXECSTACK; } EOF @@ -2701,6 +2701,22 @@ option causes a warning to be issued whenever this case occurs. Only warn once for each undefined symbol, rather than once per module which refers to it. +@kindex --warn-rwx-segments +@cindex warnings, on writeable and exectuable segments +@cindex executable segments, warnings on +@item --warn-rwx-segments +@itemx --no-warn-rwx-segments +Warn if the linker creates a loadable, non-zero sized segment that has +all three of the read, write and execute permission flags set. Such a +segment represents a potential security vulnerability. In addition +warnings will be generated if a thread local storage segment is +created with the execute permission flag set, regardless of whether or +not it has the read and/or write flags set. + +These warnings are enabled by default. They can be disabled via the +@option{--no-warn-rwx-segments} option and re-enabled via the +@option{--warn-rwx-segments} option. + @kindex --warn-section-align @cindex warnings, on section alignment @cindex section alignment, warnings on @@ -166,10 +166,13 @@ enum option_values OPTION_CTF_SHARE_TYPES, OPTION_WARN_EXECSTACK, OPTION_NO_WARN_EXECSTACK, + OPTION_WARN_RWX_SEGMENTS, + OPTION_NO_WARN_RWX_SEGMENTS, }; /* The initial parser states. */ -typedef enum input_enum { +typedef enum input_enum +{ input_selected, /* We've set the initial state. */ input_script, input_mri_script, diff --git a/ld/lexsup.c b/ld/lexsup.c index 2929fec..7819047 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -540,6 +540,10 @@ static const struct ld_option ld_options[] = '\0', NULL, N_("Warn when creating an executable stack"), TWO_DASHES }, { {"no-warn-execstack", no_argument, NULL, OPTION_NO_WARN_EXECSTACK}, '\0', NULL, N_("Do not warn when creating an executable stack"), TWO_DASHES }, + { {"warn-rwx-segments", no_argument, NULL, OPTION_WARN_RWX_SEGMENTS}, + '\0', NULL, N_("Warn when creating executable segments"), TWO_DASHES }, + { {"no-warn-rwx-segments", no_argument, NULL, OPTION_NO_WARN_RWX_SEGMENTS}, + '\0', NULL, N_("Do not warn when creating executable segments"), TWO_DASHES }, { {"warn-multiple-gp", no_argument, NULL, OPTION_WARN_MULTIPLE_GP}, '\0', NULL, N_("Warn if the multiple GP values are used"), TWO_DASHES }, { {"warn-once", no_argument, NULL, OPTION_WARN_ONCE}, @@ -925,6 +929,12 @@ parse_args (unsigned argc, char **argv) case OPTION_NO_WARN_EXECSTACK: link_info.warn_execstack = 2; break; + case OPTION_WARN_RWX_SEGMENTS: + link_info.no_warn_rwx_segments = 0; + break; + case OPTION_NO_WARN_RWX_SEGMENTS: + link_info.no_warn_rwx_segments = 1; + break; case 'e': lang_add_entry (optarg, true); break; @@ -2159,10 +2169,31 @@ elf_static_list_options (FILE *file) -z execstack Mark executable as requiring executable stack\n")); fprintf (file, _("\ -z noexecstack Mark executable as not requiring executable stack\n")); +#if DEFAULT_LD_WARN_EXECSTACK > 0 + fprintf (file, _("\ + --warn-execstack Generate a warning if the stack is executable (default)\n")); +#else fprintf (file, _("\ --warn-execstack Generate a warning if the stack is executable\n")); +#endif +#if DEFAULT_LD_WARN_EXECSTACK < 0 + fprintf (file, _("\ + --no-warn-execstack Do not generate a warning if the stack is executable (default)\n")); +#else fprintf (file, _("\ --no-warn-execstack Do not generate a warning if the stack is executable\n")); +#endif +#if DEFAULT_LD_WARN_RWX_SEGMENTS + fprintf (file, _("\ + --warn-rwx-segments Generate a warning if a LOAD segment has RWX permissions (default)\n")); + fprintf (file, _("\ + --no-warn-rwx-segments Do not generate a warning if a LOAD segments has RWX permissions\n")); +#else + fprintf (file, _("\ + --warn-rwx-segments Generate a warning if a LOAD segment has RWX permissions\n")); + fprintf (file, _("\ + --no-warn-rwx-segments Do not generate a warning if a LOAD segments has RWX permissions (default)\n")); +#endif fprintf (file, _("\ -z unique-symbol Avoid duplicated local symbol names\n")); fprintf (file, _("\ diff --git a/ld/testsuite/ld-elf/changelma.d b/ld/testsuite/ld-elf/changelma.d index 858a8db..567e72d 100644 --- a/ld/testsuite/ld-elf/changelma.d +++ b/ld/testsuite/ld-elf/changelma.d @@ -1,5 +1,5 @@ #name: changelma (pr20659) -#ld: -T changelma.lnk +#ld: -T changelma.lnk --no-warn-rwx-segments #objcopy_linked_file: --change-section-lma .dynamic+0x80000000 #readelf: -l --wide #xfail: rx-*-* diff --git a/ld/testsuite/ld-elf/elf.exp b/ld/testsuite/ld-elf/elf.exp index d561540..1b30011 100644 --- a/ld/testsuite/ld-elf/elf.exp +++ b/ld/testsuite/ld-elf/elf.exp @@ -182,6 +182,7 @@ if { [check_gc_sections_available] && ![istarget "v850-*-*"] } { proc target_defaults_to_execstack {} { if { [istarget "aarch64*-*-*"] + || [istarget "*-*-nacl"] || [istarget "arc*-*-*"] || [istarget "ia64*-*-*"] || [istarget "loongarch*-*-*"] @@ -226,7 +227,18 @@ if { [istarget *-*-*linux*] "" \ {pr23900-1.s} \ [list [list "readelf" {-Wl} $pr23900_1_exp]] \ - "pr23900-1.exe"] \ + "pr23900-1.exe"] \ + ] + + # Test the linker's generation of execstack and executable segment warnings. + # Since these are normally pruned from the linker's output we temporarily + # disable tha action here. + rename prune_warnings_extra old_prune_warnings_extra + proc prune_warnings_extra { text } { + return $text + } + + run_ld_link_tests [list \ [list "PR ld/29072 (warn about an executable .note.GNU-stack)" \ "-e 0" \ "" \ @@ -248,23 +260,39 @@ if { [istarget *-*-*linux*] {pr29072-a.s} \ {} \ "pr29072-d.exe"] \ - ] + [list "Ensure that a warning issued when creating a segment with RWX permissions" \ + "-e 0 -Tnobits-1.t --warn-rwx-segments" \ + "" \ + "" \ + {nobits-1.s} \ + {{ld rwx-segments-1.l}} \ + "rwx-segments-1.exe"] \ + [list "Ensure that a warning issued when creating a TLS segment with execute permission" \ + "-e 0 -T rwx-segments-2.t --warn-rwx-segments" \ + "" \ + "" \ + {size-2.s} \ + {{ld rwx-segments-2.l}} \ + "rwx-segments-2.exe"] \ + [list "Ensure that the warning can be suppressed" \ + "-e 0 -Tnobits-1.t --no-warn-rwx-segments" \ + "" \ + "" \ + {nobits-1.s} \ + {} \ + "rwx-segments-3.exe"] \ + ] + if { [target_defaults_to_execstack] } { - rename prune_warnings_extra old_prune_warnings_extra - proc prune_warnings_extra { text } { - return $text - } run_ld_link_tests [list \ [list "PR ld/29072 (warn about absent .note.GNU-stack)" \ - "-e 0 -z stack-size=0x123400" \ + "-e 0 -z stack-size=0x123400 --warn-execstack" \ "" \ "" \ {pr29072-b.s} \ {{ld pr29072.b.warn}} \ "pr29072-b.exe"] \ ] - rename prune_warnings_extra "" - rename old_prune_warnings_extra prune_warnings_extra } else { run_ld_link_tests [list \ [list "PR ld/29072 (ignore absent .note.GNU-stack)" \ @@ -276,6 +304,10 @@ if { [istarget *-*-*linux*] "pr29072-b.exe"] \ ] } + + # Restore the normal pruning behaviour. + rename prune_warnings_extra "" + rename old_prune_warnings_extra prune_warnings_extra } if [check_gc_sections_available] { diff --git a/ld/testsuite/ld-elf/flags1.d b/ld/testsuite/ld-elf/flags1.d index 6cd8b3f..d9034e2 100644 --- a/ld/testsuite/ld-elf/flags1.d +++ b/ld/testsuite/ld-elf/flags1.d @@ -1,5 +1,5 @@ #name: --set-section-flags test 1 (sections) -#ld: -Tflags1.ld +#ld: -Tflags1.ld --no-warn-rwx-segments #objcopy_linked_file: --set-section-flags .post_text_reserve=contents,alloc,load,readonly,code #readelf: -S --wide diff --git a/ld/testsuite/ld-elf/maxpage5.d b/ld/testsuite/ld-elf/maxpage5.d index 9d9b57a..843a976 100644 --- a/ld/testsuite/ld-elf/maxpage5.d +++ b/ld/testsuite/ld-elf/maxpage5.d @@ -1,6 +1,6 @@ #source: maxpage5.s #as: --32 -#ld: -z max-page-size=0x200000 -T maxpage5.t +#ld: -z max-page-size=0x200000 -T maxpage5.t --no-warn-rwx-segments #objcopy_linked_file: -R .foo #readelf: -l --wide #target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu* diff --git a/ld/testsuite/ld-elf/note-2.d b/ld/testsuite/ld-elf/note-2.d index aff3240..ed81703 100644 --- a/ld/testsuite/ld-elf/note-2.d +++ b/ld/testsuite/ld-elf/note-2.d @@ -1,4 +1,4 @@ -#ld: -Tnote-2.t +#ld: -Tnote-2.t --no-warn-rwx-segments #objcopy_linked_file: -R .foo #readelf: -l --wide diff --git a/ld/testsuite/ld-elf/rwx-segments-1.l b/ld/testsuite/ld-elf/rwx-segments-1.l new file mode 100644 index 0000000..432fceb --- /dev/null +++ b/ld/testsuite/ld-elf/rwx-segments-1.l @@ -0,0 +1 @@ +.*warning: .* has a LOAD segment with RWX permissions diff --git a/ld/testsuite/ld-elf/rwx-segments-2.l b/ld/testsuite/ld-elf/rwx-segments-2.l new file mode 100644 index 0000000..b830de6 --- /dev/null +++ b/ld/testsuite/ld-elf/rwx-segments-2.l @@ -0,0 +1 @@ +.*: warning: .* has a TLS segment with execute permission diff --git a/ld/testsuite/ld-elf/rwx-segments-2.t b/ld/testsuite/ld-elf/rwx-segments-2.t new file mode 100644 index 0000000..f3aef1d --- /dev/null +++ b/ld/testsuite/ld-elf/rwx-segments-2.t @@ -0,0 +1,20 @@ +PHDRS +{ + header PT_PHDR PHDRS ; + + image PT_LOAD FLAGS (5) PHDRS; + tls PT_TLS FLAGS (7); + +} +SECTIONS +{ + .text 0x100 : { *(.text) } :image + .tdata : { *(.tdata) } :image :tls + .tbss : { *(.tbss) } :image : tls + .map : { + LONG (SIZEOF (.text)) + LONG (SIZEOF (.tdata)) + LONG (SIZEOF (.tbss)) + } :image + /DISCARD/ : { *(*) } +} |