public inbox for libc-hacker@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Fix PT_GNU_RELRO support
@ 2004-01-22 16:43 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2004-01-22 16:43 UTC (permalink / raw)
  To: Ulrich Drepper; +Cc: Glibc hackers

Hi!

This patch fixes 3 things.
If ld.so is without PT_GNU_STACK but with PT_GNU_RELRO program header
(say on ppc64), elf/ld.so --library-path . /bin/echo would segfault
immediately because of writing into NULL GL(_dl_loaded).
On !DONT_USE_BOOTSTRAP_MAP arches RELRO region info for the dynamic linker
on the other side would not be recorded and thus not mprotected later.
Last, for prelinked programs we need to mprotect as well (after
_dl_resolve_conflicts finishes).

2004-01-22  Jakub Jelinek  <jakub@redhat.com>

	* elf/dl-reloc.c (_dl_relocate_object): Move PT_GNU_RELRO protection
	into...
	(_dl_protect_relro): New routine.
	* sysdeps/generic/ldsodefs.h (_dl_protect_relro): New prototype.
	* elf/rtld.c (_dl_start_final): Copy l_relro_addr and l_relro_size
	from bootstrap_map.
	(_dl_main): Don't set GL(_dl_loaded)->l_relro_{addr,size} here.
	Call _dl_protect_relro for libraries if prelinking.

--- libc/elf/dl-reloc.c.jj	2004-01-22 12:03:00.000000000 +0100
+++ libc/elf/dl-reloc.c	2004-01-22 13:43:23.000000000 +0100
@@ -311,23 +311,25 @@ _dl_relocate_object (struct link_map *l,
   /* 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);
+}
+INTDEF (_dl_relocate_object)
+
+void internal_function
+_dl_protect_relro (struct link_map *l)
+{
+  ElfW(Addr) start = ((l->l_addr + l->l_relro_addr) & ~(GL(dl_pagesize) - 1));
+  ElfW(Addr) end = ((l->l_addr + l->l_relro_addr + l->l_relro_size)
+		    & ~(GL(dl_pagesize) - 1));
+
+  if (start != end
+      && __mprotect ((void *) start, end - start, PROT_READ) < 0)
     {
-      ElfW(Addr) start = ((l->l_addr + l->l_relro_addr)
-			  & ~(GL(dl_pagesize) - 1));
-      ElfW(Addr) end = ((l->l_addr + l->l_relro_addr + l->l_relro_size)
-			& ~(GL(dl_pagesize) - 1));
-
-      if (start != end
-	  && __mprotect ((void *) start, end - start, PROT_READ) < 0)
-	{
-	  errstring = N_("\
+      const char *errstring = N_("\
 cannot apply additional memory protection after relocation");
-	  goto call_error;
-	}
+      INTUSE(_dl_signal_error) (errno, l->l_name, NULL, errstring);
     }
 }
-INTDEF (_dl_relocate_object)
-
 
 void
 internal_function __attribute_noinline__
--- libc/elf/rtld.c.jj	2004-01-22 12:02:12.000000000 +0100
+++ libc/elf/rtld.c	2004-01-22 14:08:55.000000000 +0100
@@ -224,6 +224,8 @@ _dl_start_final (void *arg, struct dl_st
   memcpy (GL(dl_rtld_map).l_info, info->l.l_info,
 	  sizeof GL(dl_rtld_map).l_info);
   GL(dl_rtld_map).l_mach = info->l.l_mach;
+  GL(dl_rtld_map).l_relro_addr = info->l.l_relro_addr;
+  GL(dl_rtld_map).l_relro_size = info->l.l_relro_size;
 #endif
   _dl_setup_hash (&GL(dl_rtld_map));
   GL(dl_rtld_map).l_opencount = 1;
@@ -794,11 +796,6 @@ of this helper program; chances are you 
 	    GL(dl_stack_flags) = ph->p_flags;
 	    break;
 	  }
-	else if (ph->p_type == PT_GNU_RELRO)
-	  {
-	    GL(dl_loaded)->l_relro_addr = ph->p_vaddr;
-	    GL(dl_loaded)->l_relro_size = ph->p_memsz;
-	  }
 
       if (__builtin_expect (mode, normal) == verify)
 	{
@@ -1676,7 +1673,11 @@ cannot allocate TLS data structures for 
 
       /* Mark all the objects so we know they have been already relocated.  */
       for (l = GL(dl_loaded); l != NULL; l = l->l_next)
-	l->l_relocated = 1;
+	{
+	  l->l_relocated = 1;
+	  if (l->l_relro_size)
+	    _dl_protect_relro (l);
+	}
 
       _dl_sysdep_start_cleanup ();
     }
--- libc/sysdeps/generic/ldsodefs.h.jj	2004-01-22 13:43:41.000000000 +0100
+++ libc/sysdeps/generic/ldsodefs.h	2004-01-22 13:47:57.000000000 +0100
@@ -697,6 +697,10 @@ extern void _dl_relocate_object_internal
 					  int lazy, int consider_profiling)
      attribute_hidden;
 
+/* Protect PT_GNU_RELRO area.  */
+extern void _dl_protect_relro (struct link_map *map)
+     internal_function attribute_hidden;
+
 /* Call _dl_signal_error with a message about an unhandled reloc type.
    TYPE is the result of ELFW(R_TYPE) (r_info), i.e. an R_<CPU>_* value.
    PLT is nonzero if this was a PLT reloc; it just affects the message.  */

	Jakub

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2004-01-22 16:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-01-22 16:43 [PATCH] Fix PT_GNU_RELRO support Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).