aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2022-05-03 11:42:24 +0100
committerNick Clifton <nickc@redhat.com>2022-05-03 11:42:24 +0100
commitba951afb99912da01a6e8434126b8fac7aa75107 (patch)
treee94ddfba29d29a82ab36d28592d6c8e7edd04350 /ld
parent46465574a925062ba7dfa72f49ba5199d7a39fc3 (diff)
downloadfsf-binutils-gdb-ba951afb99912da01a6e8434126b8fac7aa75107.zip
fsf-binutils-gdb-ba951afb99912da01a6e8434126b8fac7aa75107.tar.gz
fsf-binutils-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/NEWS24
-rw-r--r--ld/aclocal.m4193
-rw-r--r--ld/config.in12
-rwxr-xr-xld/configure75
-rw-r--r--ld/configure.ac52
-rw-r--r--ld/emultempl/elf.em3
-rw-r--r--ld/ld.texi16
-rw-r--r--ld/ldlex.h5
-rw-r--r--ld/lexsup.c31
-rw-r--r--ld/testsuite/ld-elf/changelma.d2
-rw-r--r--ld/testsuite/ld-elf/elf.exp50
-rw-r--r--ld/testsuite/ld-elf/flags1.d2
-rw-r--r--ld/testsuite/ld-elf/maxpage5.d2
-rw-r--r--ld/testsuite/ld-elf/note-2.d2
-rw-r--r--ld/testsuite/ld-elf/rwx-segments-1.l1
-rw-r--r--ld/testsuite/ld-elf/rwx-segments-2.l1
-rw-r--r--ld/testsuite/ld-elf/rwx-segments-2.t20
17 files changed, 370 insertions, 121 deletions
diff --git a/ld/NEWS b/ld/NEWS
index b845531..514d1d9 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -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
diff --git a/ld/ld.texi b/ld/ld.texi
index 6ac5344..8cad847 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -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
diff --git a/ld/ldlex.h b/ld/ldlex.h
index 1d42dc8..57ade1f 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -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/ : { *(*) }
+}