PR28824, relro security issues, x86 keep COMMONPAGESIZE relro
authorAlan Modra <amodra@gmail.com>
Wed, 2 Feb 2022 22:27:47 +0000 (08:57 +1030)
committerAlan Modra <amodra@gmail.com>
Sun, 13 Feb 2022 03:30:56 +0000 (14:00 +1030)
x86 treats MAXPAGESIZE as a memory optimisation parameter, actual
hardware paging is always COMMPAGESIZE of 4k.  Use COMMONPAGESIZE for
the end of the relro segment alignment.

The previous patch regresses pr18176, increasing the testcase file
size from 322208 to 2099872 bytes.  Fixing this on x86 will require
introducing a gap after the end of the relro segment (of up to
relropagesize-1 bytes).

PR 28824
PR 18176
* ld.h (ld_config_type): Add relro_use_commonpagesize field.
* ldexp.c (fold_segment_align): Set relropagesize depending on
relro_use_commonpagesize.
* emultempl/elf-x86.em (elf_x86_create_output_section_statements):
Set relro_use_commonpagesize.
* testsuite/ld-x86-64/pr18176.d: xfail.

ld/emultempl/elf-x86.em
ld/ld.h
ld/ldexp.c
ld/testsuite/ld-x86-64/pr18176.d

index f75521cecea7367fa4463e54742874ce28ca113b..134e4e1b61621ceb9eb55ef478a4d1affa51bcee 100644 (file)
@@ -33,6 +33,7 @@ static struct elf_linker_x86_params params;
 static void
 elf_x86_create_output_section_statements (void)
 {
+  config.relro_use_commonpagesize = true;
   _bfd_elf_linker_x86_set_options (&link_info, &params);
 }
 
diff --git a/ld/ld.h b/ld/ld.h
index f3086bf30dee354bf4f5e1329bf0ebaec2a939e3..c7e4ca3d334eafa76e23a499e5004df0a37c774b 100644 (file)
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -276,6 +276,10 @@ typedef struct
   /* If set, code and non-code sections should never be in one segment.  */
   bool separate_code;
 
+  /* TRUE if the end of the relro segment should be aligned to
+     COMMONPAGESIZE rather than MAXPAGESIZE.  */
+  bool relro_use_commonpagesize;
+
   /* The rpath separation character.  Usually ':'.  */
   char rpath_separator;
 
index a38cec7829d0fa91a55c52b53b0e385ffd2254fc..ab724074732014ad3a07e4ae510f650d31f3cb5c 100644 (file)
@@ -481,7 +481,10 @@ fold_segment_align (seg_align_type *seg, etree_value_type *lhs)
              seg->base = expld.result.value;
              seg->commonpagesize = commonpage;
              seg->maxpagesize = maxpage;
-             seg->relropagesize = maxpage;
+             if (config.relro_use_commonpagesize)
+               seg->relropagesize = commonpage;
+             else
+               seg->relropagesize = maxpage;
              seg->relro_end = 0;
            }
          else
index a99ff15ac6bee23984d9c8bb70d2c586a710150b..728c15a3dd8bfe6da02da0742140d10ab4319881 100644 (file)
@@ -3,6 +3,7 @@
 #ld: -melf_x86_64 -shared -z relro -T pr18176.t -z max-page-size=0x200000 -z common-page-size=0x1000 $NO_DT_RELR_LDFLAGS
 #readelf: -l --wide
 #target: x86_64-*-linux*
+#xfail: *-*-*
 
 #...
   GNU_RELRO      0x04bd17 0x000000000024bd17 0x000000000024bd17 0x0022e9 0x0022e9 R   0x1