about summary refs log tree commit diff
path: root/elf
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2005-12-18 06:58:22 +0000
committerUlrich Drepper <drepper@redhat.com>2005-12-18 06:58:22 +0000
commit827b70873b41363c864fb65e99829204595d0f85 (patch)
tree5d2e3811b6b0da44f18a7c8920dffdc524e3cd66 /elf
parent8292f6fc71a60e92a23be053c500f504c6802c54 (diff)
downloadglibc-827b70873b41363c864fb65e99829204595d0f85.tar.gz
glibc-827b70873b41363c864fb65e99829204595d0f85.tar.xz
glibc-827b70873b41363c864fb65e99829204595d0f85.zip
* elf/Versions [GLIBC_PRIVATE]: Export __pointer_chk_guard if defined.
	* elf/rtld.c: Define __pointer_chk_guard_local and if necessary
	__pointer_chk_guard.
	(_rtld_global_ro): Initialize _dl_pointer_guard.
	(dl_main): Initialize __pointer_chk_guard_local and either
	__pointer_chk_guard or TLS value if necessary.
	(process_envvars): Recognize and handle LD_POINTER_GUARD.
	* sysdeps/generic/ldsodefs.h (rtld_global_ro): Add _dl_pointer_guard.
	* sysdeps/i386/__longjmp.S: Use PTR_DEMANGLE for PC if defined.
	* sysdeps/x86_64/__longjmp.S: Likewise.
	* sysdeps/i386/bsd-_setjmp.S: Use PTR_MANGLE for PC if defined.
	* sysdeps/i386/bsd-_setjmp.S: Likewise.
	* sysdeps/i386/setjmp.S: Likewise.
	[IS_IN_rtld]: Avoid call to __sigjmp_save.
	* sysdeps/i386/setjmp.S: Likewise.
	* sysdeps/unix/sysv/linux/i386/sysdep.h: Define PTR_MANGLE and
	PTR_DEMANGLE.
	* sysdeps/unix/sysv/linux/x86_64/sysdep.h: Likewise.

	* sysdeps/i386/elf/setjmp.S: Removed.
	* sysdeps/i386/elf/bsd-setjmp.S: Removed.
Diffstat (limited to 'elf')
-rw-r--r--elf/Versions2
-rw-r--r--elf/rtld.c32
2 files changed, 33 insertions, 1 deletions
diff --git a/elf/Versions b/elf/Versions
index 9c53f1615e..87e27c5a7a 100644
--- a/elf/Versions
+++ b/elf/Versions
@@ -60,5 +60,7 @@ ld {
     _dl_make_stack_executable;
     # Only here for gdb while a better method is developed.
     _dl_debug_state;
+    # Pointer protection.
+    __pointer_chk_guard;
   }
 }
diff --git a/elf/rtld.c b/elf/rtld.c
index a89f89b3a5..9ef58bb328 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -90,6 +90,15 @@ INTDEF(_dl_argv)
 uintptr_t __stack_chk_guard attribute_relro;
 #endif
 
+/* Only exported for architectures that don't store the pointer guard
+   value in thread local area.  */
+uintptr_t __pointer_chk_guard_local
+     attribute_relro attribute_hidden __attribute__ ((nocommon));
+#ifndef THREAD_SET_POINTER_GUARD
+strong_alias (__pointer_chk_guard_local, __pointer_chk_guard)
+#endif
+
+
 /* List of auditing DSOs.  */
 static struct audit_list
 {
@@ -142,6 +151,7 @@ struct rtld_global_ro _rtld_global_ro attribute_relro =
     ._dl_hwcap_mask = HWCAP_IMPORTANT,
     ._dl_lazy = 1,
     ._dl_fpu_control = _FPU_DEFAULT,
+    ._dl_pointer_guard = 1,
 
     /* Function pointers.  */
     ._dl_debug_printf = _dl_debug_printf,
@@ -1823,6 +1833,20 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
   __stack_chk_guard = stack_chk_guard;
 #endif
 
+  /* Set up the pointer guard as well, if necessary.  */
+  if (GLRO(dl_pointer_guard))
+    {
+      // XXX If it is cheap, we should use a separate value.
+      uintptr_t pointer_chk_guard;
+      hp_timing_t now;
+      HP_TIMING_NOW (now);
+      pointer_chk_guard = stack_chk_guard ^ now;
+#ifdef THREAD_SET_POINTER_GUARD
+      THREAD_SET_POINTER_GUARD (pointer_chk_guard);
+#endif
+      __pointer_chk_guard_local = pointer_chk_guard;
+    }
+
   if (__builtin_expect (mode, normal) != normal)
     {
       /* We were run just to list the shared libraries.  It is
@@ -2575,7 +2599,13 @@ process_envvars (enum mode *modep)
 #endif
 	  if (!INTUSE(__libc_enable_secure)
 	      && memcmp (envline, "USE_LOAD_BIAS", 13) == 0)
-	    GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0;
+	    {
+	      GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0;
+	      break;
+	    }
+
+	  if (memcmp (envline, "POINTER_GUARD", 13) == 0)
+	    GLRO(dl_pointer_guard) = envline[14] == '0';
 	  break;
 
 	case 14: