This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

gold patch committed: If -z relro -z now, make .got.plt relro


Normally .got is a relro section but .got.plt is not, because .got.plt
needs to be changed when PLT functions are resolved lazily.  However,
when using -z now, .got.plt can also be relro.  This patch implements
that in gold, for the i386 and x86_64 targets.  This is a small security
enhancement when linking with -z now, as it makes it harder to change
the behaviour of functions called through the PLT by changing the
corresponding GOT table entry.  Committed to mainline.

Ian


2011-07-13  Ian Lance Taylor  <iant@google.com>

	* i386.cc (Target_i386::got_section): If -z now, make .got.plt a
	relro section.
	* x86_64.cc (Target_x86_64::got_section): Likewise.
	* testsuite/Makefile.am (check_PROGRAMS): Add relro_now_test.
	(relro_now_test_SOURCES): New variable.
	(relro_now_test_DEPENDENCIES): New variable.
	(relro_now_test_LDFLAGS): New variable.
	(relro_now_test_LDADD): New variable.
	(relro_now_test.so): New target.
	* testsuite/Makefile.in: Rebuild.


Index: i386.cc
===================================================================
RCS file: /cvs/src/src/gold/i386.cc,v
retrieving revision 1.139
diff -u -p -r1.139 i386.cc
--- i386.cc	12 Jul 2011 22:29:09 -0000	1.139
+++ i386.cc	13 Jul 2011 21:22:32 -0000
@@ -712,23 +712,37 @@ Target_i386::got_section(Symbol_table* s
 
       this->got_ = new Output_data_got<32, false>();
 
+      // When using -z now, we can treat .got.plt as a relro section.
+      // Without -z now, it is modified after program startup by lazy
+      // PLT relocations.
+      bool is_got_plt_relro = parameters->options().now();
+      Output_section_order got_order = (is_got_plt_relro
+					? ORDER_RELRO
+					: ORDER_RELRO_LAST);
+      Output_section_order got_plt_order = (is_got_plt_relro
+					    ? ORDER_RELRO
+					    : ORDER_NON_RELRO_FIRST);
+
       layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
 				      (elfcpp::SHF_ALLOC
 				       | elfcpp::SHF_WRITE),
-				      this->got_, ORDER_RELRO_LAST, true);
+				      this->got_, got_order, true);
 
       this->got_plt_ = new Output_data_space(4, "** GOT PLT");
       layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
 				      (elfcpp::SHF_ALLOC
 				       | elfcpp::SHF_WRITE),
-				      this->got_plt_, ORDER_NON_RELRO_FIRST,
-				      false);
+				      this->got_plt_, got_plt_order,
+				      is_got_plt_relro);
 
       // The first three entries are reserved.
       this->got_plt_->set_current_data_size(3 * 4);
 
-      // Those bytes can go into the relro segment.
-      layout->increase_relro(3 * 4);
+      if (!is_got_plt_relro)
+	{
+	  // Those bytes can go into the relro segment.
+	  layout->increase_relro(3 * 4);
+	}
 
       // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
       this->global_offset_table_ =
@@ -747,7 +761,7 @@ Target_i386::got_section(Symbol_table* s
 				      (elfcpp::SHF_ALLOC
 				       | elfcpp::SHF_WRITE),
 				      this->got_irelative_,
-				      ORDER_NON_RELRO_FIRST, false);
+				      got_plt_order, is_got_plt_relro);
 
       // If there are any TLSDESC relocations, they get GOT entries in
       // .got.plt after the jump slot entries.
@@ -756,7 +770,7 @@ Target_i386::got_section(Symbol_table* s
 				      (elfcpp::SHF_ALLOC
 				       | elfcpp::SHF_WRITE),
 				      this->got_tlsdesc_,
-				      ORDER_NON_RELRO_FIRST, false);
+				      got_plt_order, is_got_plt_relro);
     }
 
   return this->got_;
Index: x86_64.cc
===================================================================
RCS file: /cvs/src/src/gold/x86_64.cc,v
retrieving revision 1.137
diff -u -p -r1.137 x86_64.cc
--- x86_64.cc	12 Jul 2011 22:29:09 -0000	1.137
+++ x86_64.cc	13 Jul 2011 21:22:32 -0000
@@ -834,26 +834,39 @@ Target_x86_64::got_section(Symbol_table*
     {
       gold_assert(symtab != NULL && layout != NULL);
 
+      // When using -z now, we can treat .got.plt as a relro section.
+      // Without -z now, it is modified after program startup by lazy
+      // PLT relocations.
+      bool is_got_plt_relro = parameters->options().now();
+      Output_section_order got_order = (is_got_plt_relro
+					? ORDER_RELRO
+					: ORDER_RELRO_LAST);
+      Output_section_order got_plt_order = (is_got_plt_relro
+					    ? ORDER_RELRO
+					    : ORDER_NON_RELRO_FIRST);
+
       this->got_ = new Output_data_got<64, false>();
 
       layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
 				      (elfcpp::SHF_ALLOC
 				       | elfcpp::SHF_WRITE),
-				      this->got_, ORDER_RELRO_LAST,
-				      true);
+				      this->got_, got_order, true);
 
       this->got_plt_ = new Output_data_space(8, "** GOT PLT");
       layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
 				      (elfcpp::SHF_ALLOC
 				       | elfcpp::SHF_WRITE),
-				      this->got_plt_, ORDER_NON_RELRO_FIRST,
-				      false);
+				      this->got_plt_, got_plt_order,
+				      is_got_plt_relro);
 
       // The first three entries are reserved.
       this->got_plt_->set_current_data_size(3 * 8);
 
-      // Those bytes can go into the relro segment.
-      layout->increase_relro(3 * 8);
+      if (!is_got_plt_relro)
+	{
+	  // Those bytes can go into the relro segment.
+	  layout->increase_relro(3 * 8);
+	}
 
       // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
       this->global_offset_table_ =
@@ -872,7 +885,7 @@ Target_x86_64::got_section(Symbol_table*
 				      (elfcpp::SHF_ALLOC
 				       | elfcpp::SHF_WRITE),
 				      this->got_irelative_,
-				      ORDER_NON_RELRO_FIRST, false);
+				      got_plt_order, is_got_plt_relro);
 
       // If there are any TLSDESC relocations, they get GOT entries in
       // .got.plt after the jump slot and IRELATIVE entries.
@@ -881,7 +894,7 @@ Target_x86_64::got_section(Symbol_table*
 				      (elfcpp::SHF_ALLOC
 				       | elfcpp::SHF_WRITE),
 				      this->got_tlsdesc_,
-				      ORDER_NON_RELRO_FIRST, false);
+				      got_plt_order, is_got_plt_relro);
     }
 
   return this->got_;
Index: testsuite/Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v
retrieving revision 1.176
diff -u -p -r1.176 Makefile.am
--- testsuite/Makefile.am	8 Jul 2011 22:48:08 -0000	1.176
+++ testsuite/Makefile.am	13 Jul 2011 21:22:32 -0000
@@ -1163,6 +1163,14 @@ relro_test_pic.o: relro_test.cc
 relro_test.stdout: relro_test.so
 	$(TEST_READELF) -SlW relro_test.so > relro_test.stdout
 
+check_PROGRAMS += relro_now_test
+relro_now_test_SOURCES = relro_test_main.cc
+relro_now_test_DEPENDENCIES = gcctestdir/ld relro_now_test.so
+relro_now_test_LDFLAGS = -Bgcctestdir -Wl,-R,. -Wl,-z,relro -Wl,-z,now
+relro_now_test_LDADD = relro_now_test.so
+relro_now_test.so: gcctestdir/ld relro_test_pic.o
+	$(CXXLINK) -Bgcctestdir/ -shared -Wl,-z,relro -Wl,-z,now relro_test_pic.o
+
 check_PROGRAMS += relro_strip_test
 relro_strip_test_SOURCES = relro_test_main.cc
 relro_strip_test_DEPENDENCIES = gcctestdir/ld relro_strip_test.so

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]