svn commit: r315331 - in head/libexec/rtld-elf: . aarch64 amd64 arm i386 mips powerpc powerpc64 riscv sparc64

Konstantin Belousov kib at FreeBSD.org
Wed Mar 15 21:12:01 UTC 2017


Author: kib
Date: Wed Mar 15 21:11:57 2017
New Revision: 315331
URL: https://svnweb.freebsd.org/changeset/base/315331

Log:
  Implement LD_BIND_NOT knob for rtld.
  
  From the manpage:
  When set to a nonempty string, prevents modifications of the PLT slots
  when doing bindings.  As result, each call of the PLT-resolved
  function is resolved.  In combination with debug output, this provides
  complete account of all bind actions at runtime.
  
  Same feature exists on Linux and Solaris.
  
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks

Modified:
  head/libexec/rtld-elf/aarch64/reloc.c
  head/libexec/rtld-elf/aarch64/rtld_machdep.h
  head/libexec/rtld-elf/amd64/reloc.c
  head/libexec/rtld-elf/amd64/rtld_machdep.h
  head/libexec/rtld-elf/arm/reloc.c
  head/libexec/rtld-elf/arm/rtld_machdep.h
  head/libexec/rtld-elf/i386/reloc.c
  head/libexec/rtld-elf/i386/rtld_machdep.h
  head/libexec/rtld-elf/mips/reloc.c
  head/libexec/rtld-elf/mips/rtld_machdep.h
  head/libexec/rtld-elf/powerpc/reloc.c
  head/libexec/rtld-elf/powerpc/rtld_machdep.h
  head/libexec/rtld-elf/powerpc64/reloc.c
  head/libexec/rtld-elf/powerpc64/rtld_machdep.h
  head/libexec/rtld-elf/riscv/reloc.c
  head/libexec/rtld-elf/riscv/rtld_machdep.h
  head/libexec/rtld-elf/rtld.1
  head/libexec/rtld-elf/rtld.c
  head/libexec/rtld-elf/rtld.h
  head/libexec/rtld-elf/sparc64/reloc.c
  head/libexec/rtld-elf/sparc64/rtld_machdep.h

Modified: head/libexec/rtld-elf/aarch64/reloc.c
==============================================================================
--- head/libexec/rtld-elf/aarch64/reloc.c	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/aarch64/reloc.c	Wed Mar 15 21:11:57 2017	(r315331)
@@ -298,10 +298,9 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr 
 
 	assert(ELF_R_TYPE(rel->r_info) == R_AARCH64_JUMP_SLOT);
 
-	if (*where != target)
+	if (*where != target && !ld_bind_not)
 		*where = target;
-
-	return target;
+	return (target);
 }
 
 void

Modified: head/libexec/rtld-elf/aarch64/rtld_machdep.h
==============================================================================
--- head/libexec/rtld-elf/aarch64/rtld_machdep.h	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/aarch64/rtld_machdep.h	Wed Mar 15 21:11:57 2017	(r315331)
@@ -47,9 +47,8 @@ struct Struct_Obj_Entry;
 })
 
 Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
-		       const struct Struct_Obj_Entry *defobj,
-		       const struct Struct_Obj_Entry *obj,
-		       const Elf_Rel *rel);
+    const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
+    const Elf_Rel *rel);
 
 #define	make_function_pointer(def, defobj) \
 	((defobj)->relocbase + (def)->st_value)

Modified: head/libexec/rtld-elf/amd64/reloc.c
==============================================================================
--- head/libexec/rtld-elf/amd64/reloc.c	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/amd64/reloc.c	Wed Mar 15 21:11:57 2017	(r315331)
@@ -387,6 +387,20 @@ reloc_jmpslots(Obj_Entry *obj, int flags
     return 0;
 }
 
+/* Fixup the jump slot at "where" to transfer control to "target". */
+Elf_Addr
+reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
+    const struct Struct_Obj_Entry *obj, const struct Struct_Obj_Entry *refobj,
+    const Elf_Rel *rel)
+{
+#ifdef dbg
+	dbg("reloc_jmpslot: *%p = %p", where, (void *)target);
+#endif
+	if (!ld_bind_not)
+		*where = target;
+	return (target);
+}
+
 int
 reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate)
 {

Modified: head/libexec/rtld-elf/amd64/rtld_machdep.h
==============================================================================
--- head/libexec/rtld-elf/amd64/rtld_machdep.h	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/amd64/rtld_machdep.h	Wed Mar 15 21:11:57 2017	(r315331)
@@ -38,21 +38,11 @@ struct Struct_Obj_Entry;
 Elf_Dyn *rtld_dynamic_addr(void);
 #define	rtld_dynamic(obj)	rtld_dynamic_addr()
 
-/* Fixup the jump slot at "where" to transfer control to "target". */
-static inline Elf_Addr
-reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
-	      const struct Struct_Obj_Entry *obj,
-	      const struct Struct_Obj_Entry *refobj, const Elf_Rel *rel)
-{
-#ifdef dbg
-    dbg("reloc_jmpslot: *%p = %p", (void *)(where),
-	(void *)(target));
-#endif
-    (*(Elf_Addr *)(where) = (Elf_Addr)(target));
-    return target;
-}
+Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
+    const struct Struct_Obj_Entry *obj, const struct Struct_Obj_Entry *refobj,
+    const Elf_Rel *rel);
 
-#define make_function_pointer(def, defobj) \
+#define make_function_pointer(def, defobj)	\
 	((defobj)->relocbase + (def)->st_value)
 
 #define call_initfini_pointer(obj, target) \

Modified: head/libexec/rtld-elf/arm/reloc.c
==============================================================================
--- head/libexec/rtld-elf/arm/reloc.c	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/arm/reloc.c	Wed Mar 15 21:11:57 2017	(r315331)
@@ -468,15 +468,14 @@ reloc_gnu_ifunc(Obj_Entry *obj, int flag
 
 Elf_Addr
 reloc_jmpslot(Elf_Addr *where, Elf_Addr target, const Obj_Entry *defobj,
-    		const Obj_Entry *obj, const Elf_Rel *rel)
+    const Obj_Entry *obj, const Elf_Rel *rel)
 {
 
 	assert(ELF_R_TYPE(rel->r_info) == R_ARM_JUMP_SLOT);
 
-	if (*where != target)
+	if (*where != target && !ld_bind_not)
 		*where = target;
-
-	return target;
+	return (target);
 }
 
 void

Modified: head/libexec/rtld-elf/arm/rtld_machdep.h
==============================================================================
--- head/libexec/rtld-elf/arm/rtld_machdep.h	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/arm/rtld_machdep.h	Wed Mar 15 21:11:57 2017	(r315331)
@@ -38,9 +38,8 @@ struct Struct_Obj_Entry;
 #define rtld_dynamic(obj) (&_DYNAMIC)
 
 Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
-		       const struct Struct_Obj_Entry *defobj,
-		       const struct Struct_Obj_Entry *obj,
-		       const Elf_Rel *rel);
+    const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
+    const Elf_Rel *rel);
 
 #define make_function_pointer(def, defobj) \
 	((defobj)->relocbase + (def)->st_value)

Modified: head/libexec/rtld-elf/i386/reloc.c
==============================================================================
--- head/libexec/rtld-elf/i386/reloc.c	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/i386/reloc.c	Wed Mar 15 21:11:57 2017	(r315331)
@@ -344,6 +344,20 @@ reloc_jmpslots(Obj_Entry *obj, int flags
     return 0;
 }
 
+/* Fixup the jump slot at "where" to transfer control to "target". */
+Elf_Addr
+reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
+    const struct Struct_Obj_Entry *obj, const struct Struct_Obj_Entry *refobj,
+    const Elf_Rel *rel)
+{
+#ifdef dbg
+	dbg("reloc_jmpslot: *%p = %p", where, (void *)target);
+#endif
+	if (!ld_bind_not)
+		*where = target;
+	return (target);
+}
+
 int
 reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate)
 {

Modified: head/libexec/rtld-elf/i386/rtld_machdep.h
==============================================================================
--- head/libexec/rtld-elf/i386/rtld_machdep.h	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/i386/rtld_machdep.h	Wed Mar 15 21:11:57 2017	(r315331)
@@ -38,21 +38,11 @@ struct Struct_Obj_Entry;
 #define rtld_dynamic(obj) \
     ((const Elf_Dyn *)((obj)->relocbase + (Elf_Addr)&_DYNAMIC))
 
-/* Fixup the jump slot at "where" to transfer control to "target". */
-static inline Elf_Addr
-reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
-	      const struct Struct_Obj_Entry *obj,
-	      const struct Struct_Obj_Entry *refobj, const Elf_Rel *rel)
-{
-#ifdef dbg
-    dbg("reloc_jmpslot: *%p = %p", (void *)(where),
-	(void *)(target));
-#endif
-    (*(Elf_Addr *)(where) = (Elf_Addr)(target));
-    return target;
-}
+Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
+    const struct Struct_Obj_Entry *obj, const struct Struct_Obj_Entry *refobj,
+    const Elf_Rel *rel);
 
-#define make_function_pointer(def, defobj) \
+#define make_function_pointer(def, defobj)	\
 	((defobj)->relocbase + (def)->st_value)
 
 #define call_initfini_pointer(obj, target) \

Modified: head/libexec/rtld-elf/mips/reloc.c
==============================================================================
--- head/libexec/rtld-elf/mips/reloc.c	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/mips/reloc.c	Wed Mar 15 21:11:57 2017	(r315331)
@@ -274,7 +274,8 @@ _mips_rtld_bind(Obj_Entry *obj, Elf_Size
 	    obj->path,
 	    (intmax_t)reloff, defobj->strtab + def->st_name, 
 	    (void *)*where, (void *)target);
-	*where = target;
+	if (!ld_bind_not)
+		*where = target;
 	lock_release(rtld_bind_lock, &lockstate);
 	return (Elf_Addr)target;
 }

Modified: head/libexec/rtld-elf/mips/rtld_machdep.h
==============================================================================
--- head/libexec/rtld-elf/mips/rtld_machdep.h	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/mips/rtld_machdep.h	Wed Mar 15 21:11:57 2017	(r315331)
@@ -39,9 +39,8 @@ struct Struct_Obj_Entry;
 #define rtld_dynamic(obj) (&_DYNAMIC)
 
 Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
-		       const struct Struct_Obj_Entry *defobj,
-		       const struct Struct_Obj_Entry *obj,
-		       const Elf_Rel *rel);
+    const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
+    const Elf_Rel *rel);
 
 #define make_function_pointer(def, defobj) \
 	((defobj)->relocbase + (def)->st_value)

Modified: head/libexec/rtld-elf/powerpc/reloc.c
==============================================================================
--- head/libexec/rtld-elf/powerpc/reloc.c	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/powerpc/reloc.c	Wed Mar 15 21:11:57 2017	(r315331)
@@ -468,7 +468,7 @@ reloc_jmpslots(Obj_Entry *obj, int flags
  */
 Elf_Addr
 reloc_jmpslot(Elf_Addr *wherep, Elf_Addr target, const Obj_Entry *defobj,
-	      const Obj_Entry *obj, const Elf_Rel *rel)
+    const Obj_Entry *obj, const Elf_Rel *rel)
 {
 	Elf_Addr offset;
 	const Elf_Rela *rela = (const Elf_Rela *) rel;
@@ -476,6 +476,9 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr
 	dbg(" reloc_jmpslot: where=%p, target=%p",
 	    (void *)wherep, (void *)target);
 
+	if (ld_bind_not)
+		goto out;
+
 	/*
 	 * At the PLT entry pointed at by `wherep', construct
 	 * a direct transfer to the now fully resolved function
@@ -519,6 +522,7 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr
 		}
 	}
 
+out:
 	return (target);
 }
 

Modified: head/libexec/rtld-elf/powerpc/rtld_machdep.h
==============================================================================
--- head/libexec/rtld-elf/powerpc/rtld_machdep.h	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/powerpc/rtld_machdep.h	Wed Mar 15 21:11:57 2017	(r315331)
@@ -38,9 +38,8 @@ struct Struct_Obj_Entry;
 #define rtld_dynamic(obj)    (&_DYNAMIC)
 
 Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
-		       const struct Struct_Obj_Entry *defobj,
-		       const struct Struct_Obj_Entry *obj,
-		       const Elf_Rel *rel);
+    const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
+    const Elf_Rel *rel);
 
 #define make_function_pointer(def, defobj) \
 	((defobj)->relocbase + (def)->st_value)

Modified: head/libexec/rtld-elf/powerpc64/reloc.c
==============================================================================
--- head/libexec/rtld-elf/powerpc64/reloc.c	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/powerpc64/reloc.c	Wed Mar 15 21:11:57 2017	(r315331)
@@ -433,7 +433,7 @@ reloc_jmpslots(Obj_Entry *obj, int flags
  */
 Elf_Addr
 reloc_jmpslot(Elf_Addr *wherep, Elf_Addr target, const Obj_Entry *defobj,
-	      const Obj_Entry *obj, const Elf_Rel *rel)
+    const Obj_Entry *obj, const Elf_Rel *rel)
 {
 
 	/*
@@ -447,6 +447,9 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr
 	    (void *)wherep, (void *)target, *(Elf_Addr *)target,
 	    (Elf_Addr)defobj->relocbase);
 
+	if (ld_bind_not)
+		goto out;
+
 	/*
 	 * For the trampoline, the second two elements of the function
 	 * descriptor are unused, so we are fine replacing those at any time
@@ -476,11 +479,13 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr
 		((struct funcdesc *)(wherep))->toc +=
 		    (Elf_Addr)defobj->relocbase;
 	}
+out:
 #else
 	dbg(" reloc_jmpslot: where=%p, target=%p", (void *)wherep,
 	    (void *)target);
 
-	*wherep = target;
+	if (!ld_bind_not)
+		*wherep = target;
 #endif
 
 	return (target);

Modified: head/libexec/rtld-elf/powerpc64/rtld_machdep.h
==============================================================================
--- head/libexec/rtld-elf/powerpc64/rtld_machdep.h	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/powerpc64/rtld_machdep.h	Wed Mar 15 21:11:57 2017	(r315331)
@@ -38,9 +38,8 @@ struct Struct_Obj_Entry;
 #define rtld_dynamic(obj)    (&_DYNAMIC)
 
 Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
-		       const struct Struct_Obj_Entry *defobj,
-		       const struct Struct_Obj_Entry *obj,
-		       const Elf_Rel *rel);
+    const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
+    const Elf_Rel *rel);
 
 #define make_function_pointer(def, defobj) \
 	((defobj)->relocbase + (def)->st_value)

Modified: head/libexec/rtld-elf/riscv/reloc.c
==============================================================================
--- head/libexec/rtld-elf/riscv/reloc.c	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/riscv/reloc.c	Wed Mar 15 21:11:57 2017	(r315331)
@@ -226,10 +226,9 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr 
 
 	assert(ELF_R_TYPE(rel->r_info) == R_RISCV_JUMP_SLOT);
 
-	if (*where != target)
+	if (*where != target && !ld_bind_not)
 		*where = target;
-
-	return target;
+	return (target);
 }
 
 /*

Modified: head/libexec/rtld-elf/riscv/rtld_machdep.h
==============================================================================
--- head/libexec/rtld-elf/riscv/rtld_machdep.h	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/riscv/rtld_machdep.h	Wed Mar 15 21:11:57 2017	(r315331)
@@ -54,9 +54,8 @@ uint64_t set_gp(struct Struct_Obj_Entry 
 })
 
 Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
-		       const struct Struct_Obj_Entry *defobj,
-		       const struct Struct_Obj_Entry *obj,
-		       const Elf_Rel *rel);
+    const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
+    const Elf_Rel *rel);
 
 #define make_function_pointer(def, defobj) \
 	((defobj)->relocbase + (def)->st_value)

Modified: head/libexec/rtld-elf/rtld.1
==============================================================================
--- head/libexec/rtld-elf/rtld.1	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/rtld.1	Wed Mar 15 21:11:57 2017	(r315331)
@@ -28,7 +28,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 20, 2014
+.Dd March 16, 2017
 .Dt RTLD 1
 .Os
 .Sh NAME
@@ -199,6 +199,12 @@ This is intended for use within
 sandboxes, when global namespaces such as the filesystem are unavailable.
 It is consulted just after LD_LIBRARY_PATH.
 This variable is unset for set-user-ID and set-group-ID programs.
+.It Ev LD_BIND_NOT
+When set to a nonempty string, prevents modifications of the PLT slots when
+doing bindings.
+As result, each call of the PLT-resolved function is resolved.
+In combination with debug output, this provides complete account of
+all bind actions at runtime.
 .It Ev LD_BIND_NOW
 When set to a nonempty string, causes
 .Nm

Modified: head/libexec/rtld-elf/rtld.c
==============================================================================
--- head/libexec/rtld-elf/rtld.c	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/rtld.c	Wed Mar 15 21:11:57 2017	(r315331)
@@ -178,6 +178,7 @@ static char *libmap_override;	/* Maps to
 static bool trust;		/* False for setuid and setgid programs */
 static bool dangerous_ld_env;	/* True if environment variables have been
 				   used to affect the libraries loaded */
+bool ld_bind_not;		/* Disable PLT update */
 static char *ld_bind_now;	/* Environment variable for immediate binding */
 static char *ld_debug;		/* Environment variable for debugging */
 static char *ld_library_path;	/* Environment variable for search path */
@@ -416,6 +417,9 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_
     md_abi_variant_hook(aux_info);
 
     ld_bind_now = getenv(_LD("BIND_NOW"));
+    if (ld_bind_now == NULL)
+	    ld_bind_not = getenv(_LD("BIND_NOT")) != NULL;
+
     /* 
      * If the process is tainted, then we un-set the dangerous environment
      * variables.  The process will be marked as tainted until setuid(2)

Modified: head/libexec/rtld-elf/rtld.h
==============================================================================
--- head/libexec/rtld-elf/rtld.h	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/rtld.h	Wed Mar 15 21:11:57 2017	(r315331)
@@ -358,6 +358,7 @@ void *malloc_aligned(size_t size, size_t
 void free_aligned(void *ptr);
 extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
 extern Elf_Sym sym_zero;	/* For resolving undefined weak refs. */
+extern bool ld_bind_not;
 
 void dump_relocations(Obj_Entry *);
 void dump_obj_relocations(Obj_Entry *);

Modified: head/libexec/rtld-elf/sparc64/reloc.c
==============================================================================
--- head/libexec/rtld-elf/sparc64/reloc.c	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/sparc64/reloc.c	Wed Mar 15 21:11:57 2017	(r315331)
@@ -581,7 +581,9 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr
 	Elf_Addr offset;
 	Elf_Word *where;
 
-	if (rela - refobj->pltrela < 32764) {
+	if (ld_bind_not) {
+		/* Skip any PLT modifications */
+	} else if (rela - refobj->pltrela < 32764) {
 		/*
 		 * At the PLT entry pointed at by `where', we now construct
 		 * a direct transfer to the now fully resolved function

Modified: head/libexec/rtld-elf/sparc64/rtld_machdep.h
==============================================================================
--- head/libexec/rtld-elf/sparc64/rtld_machdep.h	Wed Mar 15 21:03:51 2017	(r315330)
+++ head/libexec/rtld-elf/sparc64/rtld_machdep.h	Wed Mar 15 21:11:57 2017	(r315331)
@@ -39,9 +39,8 @@ Elf_Dyn *rtld_dynamic_addr(void);
 #define	rtld_dynamic(obj)	rtld_dynamic_addr()
 
 Elf_Addr reloc_jmpslot(Elf_Addr *, Elf_Addr,
-		       const struct Struct_Obj_Entry *,
-		       const struct Struct_Obj_Entry *,
-		       const Elf_Rel *);
+    const struct Struct_Obj_Entry *, const struct Struct_Obj_Entry *,
+    const Elf_Rel *);
 
 #define make_function_pointer(def, defobj) \
 	((defobj)->relocbase + (def)->st_value)


More information about the svn-src-head mailing list