@@ -154,7 +154,8 @@ endif
tests-static-normal := tst-leaks1-static tst-array1-static tst-array5-static \
tst-dl-iter-static \
tst-tlsalign-static tst-tlsalign-extern-static \
- tst-linkall-static tst-env-setuid tst-env-setuid-tunables
+ tst-linkall-static tst-env-setuid tst-env-setuid-tunables \
+ tst-data-relro-lazy-static tst-data-relro-now-static
tests-static-internal := tst-tls1-static tst-tls2-static \
tst-ptrguard1-static tst-stackguard1-static \
tst-tls1-static-non-pie tst-libc_dlvsym-static
@@ -205,7 +206,8 @@ tests-internal += loadtest unload unload2 circleload1 \
neededtest neededtest2 neededtest3 neededtest4 \
tst-tls3 tst-tls6 tst-tls7 tst-tls8 tst-dlmopen2 \
tst-ptrguard1 tst-stackguard1 tst-libc_dlvsym \
- tst-create_format1
+ tst-create_format1 \
+ tst-data-relro-now tst-data-relro-lazy
tests-container += tst-pldd tst-dlopen-tlsmodid-container \
tst-dlopen-self-container
test-srcs = tst-pathopt
@@ -1627,3 +1629,8 @@ $(objpfx)tst-dlopenfailmod1.so: \
$(shared-thread-library) $(objpfx)tst-dlopenfaillinkmod.so
LDFLAGS-tst-dlopenfaillinkmod.so = -Wl,-soname,tst-dlopenfail-missingmod.so
$(objpfx)tst-dlopenfailmod2.so: $(shared-thread-library)
+
+LDFLAGS-tst-data-relro-lazy += -Wl,-z,relro -Wl,-z,lazy
+LDFLAGS-tst-data-relro-lazy-static += -Wl,-z,relro -Wl,-z,lazy
+LDFLAGS-tst-data-relro-now += -Wl,-z,relro -Wl,-z,now
+LDFLAGS-tst-data-relro-now-static += -Wl,-z,relro -Wl,-z,now
@@ -367,14 +367,24 @@ _dl_non_dynamic_init (void)
if (_dl_platform != NULL)
_dl_platformlen = strlen (_dl_platform);
- /* Scan for a program header telling us the stack is nonexecutable. */
if (_dl_phdr != NULL)
- for (uint_fast16_t i = 0; i < _dl_phnum; ++i)
- if (_dl_phdr[i].p_type == PT_GNU_STACK)
+ for (const ElfW(Phdr) *ph = _dl_phdr; ph < &_dl_phdr[_dl_phnum]; ++ph)
+ switch (ph->p_type)
{
- _dl_stack_flags = _dl_phdr[i].p_flags;
+ /* Check if the stack is nonexecutable. */
+ case PT_GNU_STACK:
+ _dl_stack_flags = ph->p_flags;
+ break;
+
+ case PT_GNU_RELRO:
+ _dl_main_map.l_relro_addr = ph->p_vaddr;
+ _dl_main_map.l_relro_size = ph->p_memsz;
break;
}
+
+ /* Setup relro on the binary itself. */
+ if (_dl_main_map.l_relro_size != 0)
+ _dl_protect_relro (&_dl_main_map);
}
#ifdef DL_SYSINFO_IMPLEMENTATION
new file mode 100644
@@ -0,0 +1 @@
+#include <elf/tst-data-relro.c>
new file mode 100644
@@ -0,0 +1 @@
+#include <elf/tst-data-relro.c>
new file mode 100644
@@ -0,0 +1 @@
+#include <elf/tst-data-relro.c>
new file mode 100644
@@ -0,0 +1 @@
+#include <elf/tst-data-relro.c>
new file mode 100644
@@ -0,0 +1,42 @@
+/* Test if variables places on relro section are not writable.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <signal.h>
+
+#include <support/capture_subprocess.h>
+#include <support/check.h>
+
+static volatile int val __attribute__ ((section (".data.rel.ro")));
+
+static void
+callback (void *closure)
+{
+ /* It should trigger an invalid write. */
+ val = 1;
+}
+
+int do_test (void)
+{
+ struct support_capture_subprocess result
+ = support_capture_subprocess (callback, NULL);
+ support_capture_subprocess_check (&result, "tst-relro", -SIGSEGV,
+ sc_allow_stdout);
+ return 0;
+}
+
+#include <support/test-driver.c>