]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
ld.so: Defer applying RELRO protection
authorFlorian Weimer <fweimer@redhat.com>
Tue, 24 Jan 2017 12:06:05 +0000 (13:06 +0100)
committerFlorian Weimer <fweimer@redhat.com>
Tue, 24 Jan 2017 12:06:05 +0000 (13:06 +0100)
This is a prerequisite of a future change which applies additional
cross-object relocations after _dl_relocate_object has been called.

ChangeLog
elf/dl-open.c
elf/dl-reloc.c
elf/rtld.c
sysdeps/generic/ldsodefs.h

index 1518c7f9adbff35dd4e650cb998baeb725bc3d67..dea9779520fdb9d1d7ac88ce001828200386faea 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2017-01-24  Florian Weimer  <fweimer@redhat.com>
+
+       * sysdeps/generic/ldsodefs.h (_dl_relocate_apply_relro): Declare.
+       * elf/rtld.c (relocate_doit): Add comment.
+       (dl_main): Call _dl_relocate_apply_relro.
+       * elf/dl-open.c (dl_open_worker): Likewise.
+       * elf/dl-reloc.c (_dl_relocate_object): Do not call
+       _dl_protect_relro.
+       (_dl_relocate_apply_relro): New function.
+
 2017-01-20  DJ Delorie  <dj@redhat.com>
 
        * elf/dl-tunables.c (tunable_set_val_if_valid_range): Split into ...
index cec54db413cc47e5840ebf94d2d9881bf1f7bf34..d238fb2cc52ff24f2bbdda0fd3e887a1c870ed6b 100644 (file)
@@ -552,6 +552,8 @@ TLS generation counter wrapped!  Please report this."));
        }
     }
 
+  _dl_relocate_apply_relro (new);
+
   /* Notify the debugger all new objects have been relocated.  */
   if (relocation_in_progress)
     LIBC_PROBE (reloc_complete, 3, args->nsid, r, new);
index 52311f0278695c606b7831b61d3b7cabf06f780d..926056269af87ce8884718068fd6d8a3f2c049b6 100644 (file)
@@ -306,14 +306,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 
       textrels = textrels->next;
     }
-
-  /* In case we can protect the data now that the relocations are
-     done, do it.  */
-  if (l->l_relro_size != 0)
-    _dl_protect_relro (l);
 }
 
-
 void internal_function
 _dl_protect_relro (struct link_map *l)
 {
@@ -333,6 +327,20 @@ cannot apply additional memory protection after relocation");
     }
 }
 
+void internal_function
+_dl_relocate_apply_relro (struct link_map *new)
+{
+  struct link_map **lp = new->l_searchlist.r_list;
+  struct link_map **end = lp + new->l_searchlist.r_nlist;
+  for (; lp < end; ++lp)
+    {
+      struct link_map *l = *lp;
+      if (l->l_relro_size)
+       _dl_protect_relro (l);
+    }
+}
+
+
 void
 internal_function __attribute_noinline__
 _dl_reloc_bad_type (struct link_map *map, unsigned int type, int plt)
index a036ece9568957f125a482209f6342d77313a171..16119e8c31508f7e955e7a2bb8fd92416211279f 100644 (file)
@@ -465,6 +465,7 @@ struct version_check_args
   int dotrace;
 };
 
+/* Callback function used during tracing.  */
 static void
 relocate_doit (void *a)
 {
@@ -2113,6 +2114,17 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
       HP_TIMING_ACCUM_NT (relocate_time, add);
     }
 
+  /* Activate RELRO protection.  In the prelink case, this was already
+     done earlier.  */
+  if (! prelinked)
+    {
+      /* Make sure that this covers the dynamic linker as well.
+        TODO: rtld_multiple_ref is always true because libc.so needs
+        the dynamic linker internally.  */
+      assert (rtld_multiple_ref);
+      _dl_relocate_apply_relro (main_map);
+    }
+
   /* Do any necessary cleanups for the startup OS interface code.
      We do these now so that no calls are made after rtld re-relocation
      which might be resolved to different functions than we expect.
index f26a8b20514e2c867c59bc684613ec912da547c7..469f33e8579e330050c9c18b4ac773553f6994ff 100644 (file)
@@ -863,6 +863,12 @@ extern void _dl_relocate_object (struct link_map *map,
                                 int reloc_mode, int consider_profiling)
      attribute_hidden;
 
+/* Apply RELRO protection for all objects on the search path of NEW.
+   This is the final step of relocation processing for freshly loaded
+   objects.  */
+void _dl_relocate_apply_relro (struct link_map *new)
+  internal_function attribute_hidden;
+
 /* Protect PT_GNU_RELRO area.  */
 extern void _dl_protect_relro (struct link_map *map)
      internal_function attribute_hidden;