Emit a warning when -z relro is unsupported

ld silently accepts -z relro and -z norelro for targets that lack the
necessary GNU_RELRO support.  This patch makes those targets emit a
warning instead, and adds testsuite infrastructure to detect when
relro is unsupported.

binutils/
	* testsuite/config/default.exp (ld_elf_shared_opt): Don't set.
	* testsuite/lib/binutils-common.exp (check_relro_support): New proc.
	(run_dump_test): Use check_relro_support to decide whether to pass
	extra ld option "-z norelro".
ld/
	* emultempl/elf.em (gld${EMULATION_NAME}_handle_option): Omit
	-z relro and -z norelro when target support for GNU_RELRO is lacking.
	(gld${EMULATION_NAME}_before_parse): Ignore RELRO default too.
	* emultempl/aarch64elf.em (gld${EMULATION_NAME}_before_parse): Ignore
	RELRO default when target support for GNU_RELRO is lacking.
	* emultempl/armelf.em (gld${EMULATION_NAME}_before_parse): Likewise.
	* emultempl/linux.em (gld${EMULATION_NAME}_before_parse): Likewise.
	* emultempl/scoreelf.em (gld${EMULATION_NAME}_before_parse): Likewise.
	* testsuite/config/default.exp (ld_elf_shared_opt): Don't set.
	* testsuite/ld-elf/pr16322.d: xfail when no relro support.
	* testsuite/ld-elf/pr22393-1a.d: Likewise.
	* testsuite/ld-elf/pr22393-1b.d: Likewise.
	* testsuite/ld-elf/shared.exp (pr20995-2.so, pr20995-2): Likewise.
	* testsuite/lib/ld-lib.exp (run_ld_link_tests): Use check_relro_support
	to decide whether to pass extra ld option "-z norelro".
This commit is contained in:
Alan Modra 2020-06-19 09:17:20 +09:30
parent 753d1583f7
commit 5fd104addf
15 changed files with 101 additions and 29 deletions

View File

@ -1,3 +1,10 @@
2020-06-19 Alan Modra <amodra@gmail.com>
* testsuite/config/default.exp (ld_elf_shared_opt): Don't set.
* testsuite/lib/binutils-common.exp (check_relro_support): New proc.
(run_dump_test): Use check_relro_support to decide whether to pass
extra ld option "-z norelro".
2020-06-11 Alan Modra <amodra@gmail.com> 2020-06-11 Alan Modra <amodra@gmail.com>
* readelf.c (process_mips_specific): Don't alloc memory for * readelf.c (process_mips_specific): Don't alloc memory for

View File

@ -34,8 +34,6 @@ if ![info exists LD] then {
if ![info exists LDFLAGS] then { if ![info exists LDFLAGS] then {
set LDFLAGS "" set LDFLAGS ""
} }
set ld_elf_shared_opt "-z norelro"
if ![info exists NM] then { if ![info exists NM] then {
set NM [findfile $base_dir/nm-new $base_dir/nm-new [transform nm]] set NM [findfile $base_dir/nm-new $base_dir/nm-new [transform nm]]
} }

View File

@ -308,6 +308,25 @@ proc check_pie_support { } {
return $pie_available_saved return $pie_available_saved
} }
proc check_relro_support { } {
global relro_available_saved
global ld
if {![info exists relro_available_saved]} {
remote_file host delete norelro
set ld_output [remote_exec host $ld "-z norelro"]
if { [string first "not supported" $ld_output] >= 0
|| [string first "unrecognized option" $ld_output] >= 0
|| [string first "-z norelro ignored" $ld_output] >= 0
|| [string first "cannot find norelro" $ld_output] >= 0 } {
set relro_available_saved 0
} else {
set relro_available_saved 1
}
}
return $relro_available_saved
}
# Compare two files line-by-line. FILE_1 is the actual output and FILE_2 # Compare two files line-by-line. FILE_1 is the actual output and FILE_2
# is the expected output. Ignore blank lines in either file. # is the expected output. Ignore blank lines in either file.
# #
@ -729,7 +748,7 @@ proc run_dump_test { name {extra_options {}} } {
global ADDR2LINE ADDR2LINEFLAGS AS ASFLAGS ELFEDIT ELFEDITFLAGS LD LDFLAGS global ADDR2LINE ADDR2LINEFLAGS AS ASFLAGS ELFEDIT ELFEDITFLAGS LD LDFLAGS
global NM NMFLAGS OBJCOPY OBJCOPYFLAGS OBJDUMP OBJDUMPFLAGS global NM NMFLAGS OBJCOPY OBJCOPYFLAGS OBJDUMP OBJDUMPFLAGS
global READELF READELFFLAGS STRIP STRIPFLAGS global READELF READELFFLAGS STRIP STRIPFLAGS
global copyfile env ld_elf_shared_opt runtests srcdir subdir verbose global copyfile env runtests srcdir subdir verbose
if [string match "*/*" $name] { if [string match "*/*" $name] {
set file $name set file $name
@ -1119,9 +1138,9 @@ proc run_dump_test { name {extra_options {}} } {
set ld_extra_opt "" set ld_extra_opt ""
global ld global ld
set ld "$LD" set ld "$LD"
if { [is_elf_format] && [check_shared_lib_support] } { if [check_relro_support] {
set ld_extra_opt "$ld_elf_shared_opt" set ld_extra_opt "-z norelro"
} }
# Add -L$srcdir/$subdir so that the linker command can use # Add -L$srcdir/$subdir so that the linker command can use
# linker scripts in the source directory. # linker scripts in the source directory.

View File

@ -1,3 +1,21 @@
2020-06-19 Alan Modra <amodra@gmail.com>
* emultempl/elf.em (gld${EMULATION_NAME}_handle_option): Omit
-z relro and -z norelro when target support for GNU_RELRO is lacking.
(gld${EMULATION_NAME}_before_parse): Ignore RELRO default too.
* emultempl/aarch64elf.em (gld${EMULATION_NAME}_before_parse): Ignore
RELRO default when target support for GNU_RELRO is lacking.
* emultempl/armelf.em (gld${EMULATION_NAME}_before_parse): Likewise.
* emultempl/linux.em (gld${EMULATION_NAME}_before_parse): Likewise.
* emultempl/scoreelf.em (gld${EMULATION_NAME}_before_parse): Likewise.
* testsuite/config/default.exp (ld_elf_shared_opt): Don't set.
* testsuite/ld-elf/pr16322.d: xfail when no relro support.
* testsuite/ld-elf/pr22393-1a.d: Likewise.
* testsuite/ld-elf/pr22393-1b.d: Likewise.
* testsuite/ld-elf/shared.exp (pr20995-2.so, pr20995-2): Likewise.
* testsuite/lib/ld-lib.exp (run_ld_link_tests): Use check_relro_support
to decide whether to pass extra ld option "-z norelro".
2020-06-17 H.J. Lu <hongjiu.lu@intel.com> 2020-06-17 H.J. Lu <hongjiu.lu@intel.com>
* testsuite/ld-elf/linux-x86.exp (check_pr25749a): Append "-w" * testsuite/ld-elf/linux-x86.exp (check_pr25749a): Append "-w"

View File

@ -47,7 +47,13 @@ gld${EMULATION_NAME}_before_parse (void)
config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`; config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`;
config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`; config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`;
link_info.check_relocs_after_open_input = TRUE; link_info.check_relocs_after_open_input = TRUE;
EOF
if test -n "$COMMONPAGESIZE"; then
fragment <<EOF
link_info.relro = DEFAULT_LD_Z_RELRO; link_info.relro = DEFAULT_LD_Z_RELRO;
EOF
fi
fragment <<EOF
} }
static void static void

View File

@ -60,7 +60,13 @@ gld${EMULATION_NAME}_before_parse (void)
config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`; config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`;
config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`; config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`;
link_info.check_relocs_after_open_input = TRUE; link_info.check_relocs_after_open_input = TRUE;
EOF
if test -n "$COMMONPAGESIZE"; then
fragment <<EOF
link_info.relro = DEFAULT_LD_Z_RELRO; link_info.relro = DEFAULT_LD_Z_RELRO;
EOF
fi
fragment <<EOF
} }
static void static void

View File

@ -82,7 +82,13 @@ gld${EMULATION_NAME}_before_parse (void)
config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`; config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`;
config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`; config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`;
link_info.check_relocs_after_open_input = TRUE; link_info.check_relocs_after_open_input = TRUE;
EOF
if test -n "$COMMONPAGESIZE"; then
fragment <<EOF
link_info.relro = DEFAULT_LD_Z_RELRO; link_info.relro = DEFAULT_LD_Z_RELRO;
EOF
fi
fragment <<EOF
link_info.separate_code = DEFAULT_LD_Z_SEPARATE_CODE; link_info.separate_code = DEFAULT_LD_Z_SEPARATE_CODE;
} }
@ -805,10 +811,16 @@ fragment <<EOF
link_info.combreloc = FALSE; link_info.combreloc = FALSE;
else if (strcmp (optarg, "nocopyreloc") == 0) else if (strcmp (optarg, "nocopyreloc") == 0)
link_info.nocopyreloc = TRUE; link_info.nocopyreloc = TRUE;
EOF
if test -n "$COMMONPAGESIZE"; then
fragment <<EOF
else if (strcmp (optarg, "relro") == 0) else if (strcmp (optarg, "relro") == 0)
link_info.relro = TRUE; link_info.relro = TRUE;
else if (strcmp (optarg, "norelro") == 0) else if (strcmp (optarg, "norelro") == 0)
link_info.relro = FALSE; link_info.relro = FALSE;
EOF
fi
fragment <<EOF
else if (strcmp (optarg, "separate-code") == 0) else if (strcmp (optarg, "separate-code") == 0)
link_info.separate_code = TRUE; link_info.separate_code = TRUE;
else if (strcmp (optarg, "noseparate-code") == 0) else if (strcmp (optarg, "noseparate-code") == 0)

View File

@ -52,7 +52,13 @@ gld${EMULATION_NAME}_before_parse (void)
input_flags.dynamic = TRUE; input_flags.dynamic = TRUE;
config.has_shared = TRUE; config.has_shared = TRUE;
link_info.check_relocs_after_open_input = TRUE; link_info.check_relocs_after_open_input = TRUE;
EOF
if test -n "$COMMONPAGESIZE"; then
fragment <<EOF
link_info.relro = DEFAULT_LD_Z_RELRO; link_info.relro = DEFAULT_LD_Z_RELRO;
EOF
fi
fragment <<EOF
} }
/* Try to open a dynamic archive. This is where we know that Linux /* Try to open a dynamic archive. This is where we know that Linux

View File

@ -40,7 +40,13 @@ gld${EMULATION_NAME}_before_parse (void)
config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`; config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`;
config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`; config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`;
link_info.check_relocs_after_open_input = TRUE; link_info.check_relocs_after_open_input = TRUE;
EOF
if test -n "$COMMONPAGESIZE"; then
fragment <<EOF
link_info.relro = DEFAULT_LD_Z_RELRO; link_info.relro = DEFAULT_LD_Z_RELRO;
EOF
fi
fragment <<EOF
} }
static void static void

View File

@ -76,9 +76,6 @@ if {[file exists tmpdir/libpath.exp]} {
} }
} }
# Many ELF testcases expect that "-z relro" is off.
set ld_elf_shared_opt "-z norelro"
# The "make check" target in the Makefile passes in # The "make check" target in the Makefile passes in
# "CC=$(CC_FOR_TARGET)". But, if the user invokes runtest directly # "CC=$(CC_FOR_TARGET)". But, if the user invokes runtest directly
# (as when testing an installed linker), these flags may not be set. # (as when testing an installed linker), these flags may not be set.

View File

@ -2,6 +2,7 @@
#readelf: -l --wide #readelf: -l --wide
#target: *-*-linux-gnu *-*-gnu* *-*-nacl* arm*-*-uclinuxfdpiceabi #target: *-*-linux-gnu *-*-gnu* *-*-nacl* arm*-*-uclinuxfdpiceabi
#xfail: ![check_shared_lib_support] #xfail: ![check_shared_lib_support]
#xfail: ![check_relro_support]
#... #...
GNU_RELRO .* GNU_RELRO .*

View File

@ -3,6 +3,7 @@
#readelf: -l --wide #readelf: -l --wide
#target: *-*-linux-gnu *-*-gnu* *-*-nacl* arm*-*-uclinuxfdpiceabi #target: *-*-linux-gnu *-*-gnu* *-*-nacl* arm*-*-uclinuxfdpiceabi
#xfail: ![check_shared_lib_support] #xfail: ![check_shared_lib_support]
#xfail: ![check_relro_support]
#failif #failif
#... #...

View File

@ -3,6 +3,7 @@
#readelf: -l --wide #readelf: -l --wide
#target: *-*-linux-gnu *-*-gnu* *-*-nacl* arm*-*-uclinuxfdpiceabi #target: *-*-linux-gnu *-*-gnu* *-*-nacl* arm*-*-uclinuxfdpiceabi
#xfail: ![check_shared_lib_support] #xfail: ![check_shared_lib_support]
#xfail: ![check_relro_support]
#failif #failif
#... #...

View File

@ -454,16 +454,6 @@ run_ld_link_tests [list \
{pr20995b.s} {} "pr20995.so"] \ {pr20995b.s} {} "pr20995.so"] \
] ]
# xfail on arm*-*-eabi*. The list can be enlarged to those targets that
# don't support GNU_RELRO. For more details, please see discussions at:
# https://sourceware.org/ml/binutils/2017-01/msg00441.html
run_ld_link_tests [list \
[list "Build pr20995-2.so" \
"-shared -z relro" "" "$AFLAGS_PIC" \
{pr20995c.s} {{readelf {-l --wide} pr20995-2so.r}} "pr20995-2.so"] \
] "tic6x-*-*" "arm*-*-eabi*" "hppa*64*-*-hpux*" "aarch64*-*-elf*" \
"*-*-lynxos*" "arm*-*-nto*" "i?86-*-nto*" "sh*-*-nto*"
# These targets don't copy dynamic variables into .bss. # These targets don't copy dynamic variables into .bss.
setup_xfail "alpha-*-*" "bfin-*-*" "ia64-*-*" "xtensa-*-*" setup_xfail "alpha-*-*" "bfin-*-*" "ia64-*-*" "xtensa-*-*"
# or don't have .data.rel.ro # or don't have .data.rel.ro
@ -474,16 +464,22 @@ run_ld_link_tests [list \
"$LFLAGS" "tmpdir/pr20995.so" "$AFLAGS_NONPIC" \ "$LFLAGS" "tmpdir/pr20995.so" "$AFLAGS_NONPIC" \
{pr20995a.s} {{readelf {-S --wide} pr20995.r}} "pr20995"]] {pr20995a.s} {{readelf {-S --wide} pr20995.r}} "pr20995"]]
# xfail on arm*-*-eabi* is particularly because of no support of GNU_RELRO. # xfail on targets that don't support GNU_RELRO.
# Please see the link above for details. # For more details, please see discussions at:
setup_xfail "alpha-*-*" "bfin-*-*" "ia64-*-*" "xtensa-*-*" "arm*-*-eabi*" # https://sourceware.org/ml/binutils/2017-01/msg00441.html
setup_xfail "hppa*64*-*-hpux*" "aarch64*-*-elf*" "tic6x-*-*" run_ld_link_tests [list \
[list "Build pr20995-2.so" \
"-shared -z relro" "" "$AFLAGS_PIC" \
{pr20995c.s} {{readelf {-l --wide} pr20995-2so.r}} "pr20995-2.so"] \
] {![check_relro_support]}
setup_xfail alpha-*-* xtensa-*-*
run_ld_link_tests [list \ run_ld_link_tests [list \
[list \ [list \
"pr20995-2" \ "pr20995-2" \
"$LFLAGS" "tmpdir/pr20995-2.so" "$AFLAGS_NONPIC" \ "$LFLAGS" "tmpdir/pr20995-2.so" "$AFLAGS_NONPIC" \
{pr20995a.s} {{readelf {-S --wide} pr20995.r}} "pr20995-2"] {pr20995a.s} {{readelf {-S --wide} pr20995.r}} "pr20995-2"]
] "*-*-lynxos*" "arm*-*-nto*" "i?86-*-nto*" "sh*-*-nto*" ] {![check_relro_support]}
run_ld_link_tests [list \ run_ld_link_tests [list \
[list "Build pr22374 shared library" \ [list "Build pr22374 shared library" \

View File

@ -463,12 +463,10 @@ proc run_ld_link_tests { ldtests args } {
global CFLAGS global CFLAGS
global runtests global runtests
global exec_output global exec_output
global ld_elf_shared_opt
if { [is_elf_format] && [check_shared_lib_support] } { set ld_extra_opt ""
set ld_extra_opt "$ld_elf_shared_opt" if [check_relro_support] {
} else { set ld_extra_opt "-z norelro"
set ld_extra_opt ""
} }
foreach testitem $ldtests { foreach testitem $ldtests {