[PR,symtab/21126] Fix handling of fully zeroed PT_GNU_RELRO

Message ID 001a113dea12f95c96054821cbf0@google.com
State New, archived
Headers

Commit Message

Terekhov, Mikhail via Gdb-patches Feb. 10, 2017, 12:01 a.m. UTC
  Hi. I tripped over this on Fuchsia.

strip can now fully zero out the PT_GNU_RELRO segment header.
I don't see a need to test this segment at all. If the PT_LOAD segments
match I'm ok with saying "good to go".


     Fix handling of fully zeroed PT_GNU_RELRO

     From PR 21126:
     strip can now fully zero out PT_GNU_RELRO segments
     (as in even the segment type is changed to PT_NULL).

     The bug has been seen with recent versions of strip on clang-built  
binaries
     when used with gdbserver.
     gdb's exec_bfd needs to be the non-stripped version and the program  
running
     needs to be the stripped version in order to see the bug.

     gdb/ChangeLog:

         PR symtab/21126
         * solib-svr4.c (svr4_exec_displacment): Ignore PT_GNU_RELRO segment.

     testsuite/ChangeLog:

         PR symtab/21126
         * gdb.server/stripped-pie.exp: New testcase.

2017-02-09  Doug Evans  <dje@google.com>

	PR symtab/21126
	* solib-svr4.c (svr4_exec_displacment): Ignore PT_GNU_RELRO segment.

2017-02-09  Doug Evans  <dje@google.com>

	PR symtab/21126
	* gdb.server/stripped-pie.exp: New testcase.

+
+# If we can run to main, we're good.
+runto main message
  

Comments

Luis Machado Feb. 13, 2017, 6:49 p.m. UTC | #1
On 02/09/2017 06:01 PM, Doug Evans via gdb-patches wrote:
> diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
> index 4f52251a62..82904fe588 100644
> --- a/gdb/solib-svr4.c
> +++ b/gdb/solib-svr4.c
> @@ -2777,25 +2777,10 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
>
>            /* Strip modifies the flags and alignment of PT_GNU_RELRO.
>               CentOS-5 has problems with filesz, memsz as well.
> -             See PR 11786.  */
> +             And strip may now fully zero out the section, so just
> +             ignore it. See PR 11786, 21126.  */

Two spaces after period.

> @@ -2908,25 +2893,10 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
>
>            /* Strip modifies the flags and alignment of PT_GNU_RELRO.
>               CentOS-5 has problems with filesz, memsz as well.
> -             See PR 11786.  */
> +             And strip may now fully zero out the section, so just
> +             ignore it. See PR 11786, 21126.  */

Two spaces after period.

> diff --git a/gdb/testsuite/gdb.server/stripped-pie.exp
> b/gdb/testsuite/gdb.server/stripped-pie.exp
> new file mode 100644
> index 0000000000..330b0597b8
> --- /dev/null
> +++ b/gdb/testsuite/gdb.server/stripped-pie.exp
> @@ -0,0 +1,55 @@
> +# Copyright 2017 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program 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 General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
> +
> +# PR 21126
> +# strip may completely nullify the PT_GNU_RELRO segment header.
> +# Seeing this bug requires exec_bfd to be from the non-stripped binary,
> +# with the in-memory image being from the stripped binary. And it seems
> +# to require clang-built executables, not sure what the difference is that
> +# triggers the complete nullification.
> +
> +load_lib gdbserver-support.exp
> +
> +standard_testfile server.c
> +
> +if { [skip_gdbserver_tests] } {

untested "skipping gdbserver tests"?

Otherwise looks OK to me.
  

Patch

diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 4f52251a62..82904fe588 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -2777,25 +2777,10 @@  svr4_exec_displacement (CORE_ADDR *displacementp)

  		  /* Strip modifies the flags and alignment of PT_GNU_RELRO.
  		     CentOS-5 has problems with filesz, memsz as well.
-		     See PR 11786.  */
+		     And strip may now fully zero out the section, so just
+		     ignore it. See PR 11786, 21126.  */
  		  if (phdr2[i].p_type == PT_GNU_RELRO)
-		    {
-		      Elf32_External_Phdr tmp_phdr = *phdrp;
-		      Elf32_External_Phdr tmp_phdr2 = *phdr2p;
-
-		      memset (tmp_phdr.p_filesz, 0, 4);
-		      memset (tmp_phdr.p_memsz, 0, 4);
-		      memset (tmp_phdr.p_flags, 0, 4);
-		      memset (tmp_phdr.p_align, 0, 4);
-		      memset (tmp_phdr2.p_filesz, 0, 4);
-		      memset (tmp_phdr2.p_memsz, 0, 4);
-		      memset (tmp_phdr2.p_flags, 0, 4);
-		      memset (tmp_phdr2.p_align, 0, 4);
-
-		      if (memcmp (&tmp_phdr, &tmp_phdr2, sizeof (tmp_phdr))
-			  == 0)
-			continue;
-		    }
+		    continue;

  		  /* prelink can convert .plt SHT_NOBITS to SHT_PROGBITS.  */
  		  plt2_asect = bfd_get_section_by_name (exec_bfd, ".plt");
@@ -2908,25 +2893,10 @@  svr4_exec_displacement (CORE_ADDR *displacementp)

  		  /* Strip modifies the flags and alignment of PT_GNU_RELRO.
  		     CentOS-5 has problems with filesz, memsz as well.
-		     See PR 11786.  */
+		     And strip may now fully zero out the section, so just
+		     ignore it. See PR 11786, 21126.  */
  		  if (phdr2[i].p_type == PT_GNU_RELRO)
-		    {
-		      Elf64_External_Phdr tmp_phdr = *phdrp;
-		      Elf64_External_Phdr tmp_phdr2 = *phdr2p;
-
-		      memset (tmp_phdr.p_filesz, 0, 8);
-		      memset (tmp_phdr.p_memsz, 0, 8);
-		      memset (tmp_phdr.p_flags, 0, 4);
-		      memset (tmp_phdr.p_align, 0, 8);
-		      memset (tmp_phdr2.p_filesz, 0, 8);
-		      memset (tmp_phdr2.p_memsz, 0, 8);
-		      memset (tmp_phdr2.p_flags, 0, 4);
-		      memset (tmp_phdr2.p_align, 0, 8);
-
-		      if (memcmp (&tmp_phdr, &tmp_phdr2, sizeof (tmp_phdr))
-			  == 0)
-			continue;
-		    }
+		    continue;

  		  /* prelink can convert .plt SHT_NOBITS to SHT_PROGBITS.  */
  		  plt2_asect = bfd_get_section_by_name (exec_bfd, ".plt");
diff --git a/gdb/testsuite/gdb.server/stripped-pie.exp  
b/gdb/testsuite/gdb.server/stripped-pie.exp
new file mode 100644
index 0000000000..330b0597b8
--- /dev/null
+++ b/gdb/testsuite/gdb.server/stripped-pie.exp
@@ -0,0 +1,55 @@ 
+# Copyright 2017 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# PR 21126
+# strip may completely nullify the PT_GNU_RELRO segment header.
+# Seeing this bug requires exec_bfd to be from the non-stripped binary,
+# with the in-memory image being from the stripped binary. And it seems
+# to require clang-built executables, not sure what the difference is that
+# triggers the complete nullification.
+
+load_lib gdbserver-support.exp
+
+standard_testfile server.c
+
+if { [skip_gdbserver_tests] } {
+    return 0
+}
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug  
additional_flags=-fpie "ldflags=-pie -Wl,-z,relro"}]} {
+    return -1
+}
+
+set stripped_binfile ${binfile}.stripped
+
+set strip_program [transform strip]
+remote_file host delete ${stripped_binfile}
+if [run_on_host "strip" "$strip_program" "-g -o ${stripped_binfile}  
$binfile"] {
+    return -1
+}
+
+clean_restart ${binfile}
+
+# Make sure we're disconnected, in case we're testing with an
+# extended-remote board, therefore already connected.
+gdb_test "disconnect" ".*"
+
+set remote_binfile [gdb_remote_download target $stripped_binfile]
+gdbserver_start_extended
+
+gdb_test_no_output "set remote exec-file $remote_binfile" "set remote  
exec-file"