alloc = i_ehdrp->e_phnum;
if (alloc != 0)
{
+ if (link_info != NULL && ! link_info->no_warn_rwx_segments)
+ {
+ /* Memory resident segments with non-zero size and RWX permissions are a
+ security risk, so we generate a warning here if we are creating any. */
+ unsigned int i;
+
+ for (i = 0; i < alloc; i++)
+ {
+ const Elf_Internal_Phdr * phdr = tdata->phdr + i;
+
+ if (phdr->p_memsz == 0)
+ continue;
+
+ if (phdr->p_type == PT_TLS && (phdr->p_flags & PF_X))
+ _bfd_error_handler (_("warning: %pB has a TLS segment with execute permission"),
+ abfd);
+ else if (phdr->p_type == PT_LOAD
+ && (phdr->p_flags & (PF_R | PF_W | PF_X)) == (PF_R | PF_W | PF_X))
+ _bfd_error_handler (_("warning: %pB has a LOAD segment with RWX permissions"),
+ abfd);
+ }
+ }
+
if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) != 0
|| bed->s->write_out_phdrs (abfd, tdata->phdr, alloc) != 0)
return false;
break;
}
}
- else if (bed->default_execstack)
+ else if (bed->default_execstack && info->default_execstack)
{
exec = PF_X;
emptyobj = inputobj;
regsub -all "(^|\n)(\[^\n\]*: Warning: Gap in build notes detected from\[^\n\]*\n?)+" $text "\\1" text
regsub -all "(^|\n)(\[^\n\]*: warning:\[^\n\]*missing \\.note\\.GNU-stack section\[^\n\]*\n?)+" $text "\\1" text
regsub -all "(^|\n)(\[^\n\]*: NOTE: This behaviour is deprecated\[^\n\]*\n?)+" $text "\\1" text
+ regsub -all "(^|\n)(\[^\n\]*: warning:\[^\n\]*has a LOAD segment with RWX permissions\[^\n\]*\n?)+" $text "\\1" text
+ regsub -all "(^|\n)(\[^\n\]*: warning:\[^\n\]*has a TLS segment with execute permission\[^\n\]*\n?)+" $text "\\1" text
return $text
}
flags. */
unsigned int noexecstack: 1;
- /* Tri-state variable: 0 => not set by user; 1 => set, warnings
- enabled; 2 => warnings disabled; 3 => unused. */
+ /* Tri-state variable:
+ 0 => warn if the linker is creating an executable stack, but
+ execstack (above) is 0.
+ 1 => warn if the linker is creating an executable stack; ignores
+ the value of execstack.
+ 2 => do not warn.
+ 3 => not used. */
unsigned int warn_execstack: 2;
+ /* TRUE if warnings should not be generated for TLS segments with eXecute
+ permission or LOAD segments with RWX permissions. */
+ unsigned int no_warn_rwx_segments: 1;
+
+ /* TRUE if the stack can be made executable because of the absence of a
+ .note.GNU-stack section in an input file. Note - even if this field
+ is set, some targets may choose to ignore the setting and not create
+ an executable stack. */
+ unsigned int default_execstack : 1;
+
/* TRUE if we want to produced optimized output files. This might
need much more time and therefore must be explicitly selected. */
unsigned int optimize: 1;
-*- 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
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.
-# 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,
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,
# 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
])
# 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,
# 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,
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,
# 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],
# 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
# -----------------------------
# 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,
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.
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
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,
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,
# 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,
# 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,
# 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,
# 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,
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,
# 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,
# 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,
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,
_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,
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,
# 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,
/* 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
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
--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
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
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
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.
_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
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,
$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
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
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
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,
'\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},
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;
-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, _("\
#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-*-*
proc target_defaults_to_execstack {} {
if { [istarget "aarch64*-*-*"]
+ || [istarget "*-*-nacl"]
|| [istarget "arc*-*-*"]
|| [istarget "ia64*-*-*"]
|| [istarget "loongarch*-*-*"]
"" \
{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" \
"" \
{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)" \
"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] {
#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
#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*
-#ld: -Tnote-2.t
+#ld: -Tnote-2.t --no-warn-rwx-segments
#objcopy_linked_file: -R .foo
#readelf: -l --wide
--- /dev/null
+.*warning: .* has a LOAD segment with RWX permissions
--- /dev/null
+.*: warning: .* has a TLS segment with execute permission
--- /dev/null
+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/ : { *(*) }
+}