summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2017-03-29 11:03:08 +0000
committerkib <kib@FreeBSD.org>2017-03-29 11:03:08 +0000
commit2831f74217fb010469f2c93f062dfaf20ea0be8e (patch)
tree1257f910b0d0b1d9c206c83de7a6c1fbfd40344b /libexec
parent8c7458908683635acf91691601f8a542f4067505 (diff)
downloadFreeBSD-src-2831f74217fb010469f2c93f062dfaf20ea0be8e.zip
FreeBSD-src-2831f74217fb010469f2c93f062dfaf20ea0be8e.tar.gz
MFC r315331:
Implement LD_BIND_NOT knob for rtld. MFC r315337: Disable LD_BIND_NOT for setugid processes. MFC r315429 (by jilles): Document that LD_BIND_NOT is unset for setugid processes.
Diffstat (limited to 'libexec')
-rw-r--r--libexec/rtld-elf/aarch64/reloc.c5
-rw-r--r--libexec/rtld-elf/aarch64/rtld_machdep.h5
-rw-r--r--libexec/rtld-elf/amd64/reloc.c14
-rw-r--r--libexec/rtld-elf/amd64/rtld_machdep.h18
-rw-r--r--libexec/rtld-elf/arm/reloc.c7
-rw-r--r--libexec/rtld-elf/arm/rtld_machdep.h5
-rw-r--r--libexec/rtld-elf/i386/reloc.c14
-rw-r--r--libexec/rtld-elf/i386/rtld_machdep.h18
-rw-r--r--libexec/rtld-elf/mips/reloc.c3
-rw-r--r--libexec/rtld-elf/mips/rtld_machdep.h5
-rw-r--r--libexec/rtld-elf/powerpc/reloc.c6
-rw-r--r--libexec/rtld-elf/powerpc/rtld_machdep.h5
-rw-r--r--libexec/rtld-elf/powerpc64/reloc.c9
-rw-r--r--libexec/rtld-elf/powerpc64/rtld_machdep.h5
-rw-r--r--libexec/rtld-elf/riscv/reloc.c5
-rw-r--r--libexec/rtld-elf/riscv/rtld_machdep.h5
-rw-r--r--libexec/rtld-elf/rtld.19
-rw-r--r--libexec/rtld-elf/rtld.c6
-rw-r--r--libexec/rtld-elf/rtld.h1
-rw-r--r--libexec/rtld-elf/sparc64/reloc.c4
-rw-r--r--libexec/rtld-elf/sparc64/rtld_machdep.h5
21 files changed, 88 insertions, 66 deletions
diff --git a/libexec/rtld-elf/aarch64/reloc.c b/libexec/rtld-elf/aarch64/reloc.c
index 3f9de07..41f9396 100644
--- a/libexec/rtld-elf/aarch64/reloc.c
+++ b/libexec/rtld-elf/aarch64/reloc.c
@@ -293,10 +293,9 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr target, const Obj_Entry *defobj,
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
diff --git a/libexec/rtld-elf/aarch64/rtld_machdep.h b/libexec/rtld-elf/aarch64/rtld_machdep.h
index 84f060f..eb72a61 100644
--- a/libexec/rtld-elf/aarch64/rtld_machdep.h
+++ b/libexec/rtld-elf/aarch64/rtld_machdep.h
@@ -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)
diff --git a/libexec/rtld-elf/amd64/reloc.c b/libexec/rtld-elf/amd64/reloc.c
index 10b9332..47d9522 100644
--- a/libexec/rtld-elf/amd64/reloc.c
+++ b/libexec/rtld-elf/amd64/reloc.c
@@ -387,6 +387,20 @@ reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
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)
{
diff --git a/libexec/rtld-elf/amd64/rtld_machdep.h b/libexec/rtld-elf/amd64/rtld_machdep.h
index 0a6354f..df1aff6 100644
--- a/libexec/rtld-elf/amd64/rtld_machdep.h
+++ b/libexec/rtld-elf/amd64/rtld_machdep.h
@@ -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) \
diff --git a/libexec/rtld-elf/arm/reloc.c b/libexec/rtld-elf/arm/reloc.c
index 1b022c5..c1d50c0 100644
--- a/libexec/rtld-elf/arm/reloc.c
+++ b/libexec/rtld-elf/arm/reloc.c
@@ -468,15 +468,14 @@ reloc_gnu_ifunc(Obj_Entry *obj, int flags,
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
diff --git a/libexec/rtld-elf/arm/rtld_machdep.h b/libexec/rtld-elf/arm/rtld_machdep.h
index 2c1a2b8..5639def 100644
--- a/libexec/rtld-elf/arm/rtld_machdep.h
+++ b/libexec/rtld-elf/arm/rtld_machdep.h
@@ -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)
diff --git a/libexec/rtld-elf/i386/reloc.c b/libexec/rtld-elf/i386/reloc.c
index 42efcf7..e97121b 100644
--- a/libexec/rtld-elf/i386/reloc.c
+++ b/libexec/rtld-elf/i386/reloc.c
@@ -344,6 +344,20 @@ reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
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)
{
diff --git a/libexec/rtld-elf/i386/rtld_machdep.h b/libexec/rtld-elf/i386/rtld_machdep.h
index 1ffdca4..ea9df63 100644
--- a/libexec/rtld-elf/i386/rtld_machdep.h
+++ b/libexec/rtld-elf/i386/rtld_machdep.h
@@ -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) \
diff --git a/libexec/rtld-elf/mips/reloc.c b/libexec/rtld-elf/mips/reloc.c
index a3ba2f4..5dc5c79 100644
--- a/libexec/rtld-elf/mips/reloc.c
+++ b/libexec/rtld-elf/mips/reloc.c
@@ -259,7 +259,8 @@ _mips_rtld_bind(Obj_Entry *obj, Elf_Size reloff)
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;
}
diff --git a/libexec/rtld-elf/mips/rtld_machdep.h b/libexec/rtld-elf/mips/rtld_machdep.h
index 484af1b..8536061 100644
--- a/libexec/rtld-elf/mips/rtld_machdep.h
+++ b/libexec/rtld-elf/mips/rtld_machdep.h
@@ -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)
diff --git a/libexec/rtld-elf/powerpc/reloc.c b/libexec/rtld-elf/powerpc/reloc.c
index dea564b..8d4f87c 100644
--- a/libexec/rtld-elf/powerpc/reloc.c
+++ b/libexec/rtld-elf/powerpc/reloc.c
@@ -468,7 +468,7 @@ reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
*/
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 target, const Obj_Entry *defobj,
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 target, const Obj_Entry *defobj,
}
}
+out:
return (target);
}
diff --git a/libexec/rtld-elf/powerpc/rtld_machdep.h b/libexec/rtld-elf/powerpc/rtld_machdep.h
index 92bbf9a..b4e8b15 100644
--- a/libexec/rtld-elf/powerpc/rtld_machdep.h
+++ b/libexec/rtld-elf/powerpc/rtld_machdep.h
@@ -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)
diff --git a/libexec/rtld-elf/powerpc64/reloc.c b/libexec/rtld-elf/powerpc64/reloc.c
index e6198f0..eca489d 100644
--- a/libexec/rtld-elf/powerpc64/reloc.c
+++ b/libexec/rtld-elf/powerpc64/reloc.c
@@ -433,7 +433,7 @@ reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
*/
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 target, const Obj_Entry *defobj,
(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 target, const Obj_Entry *defobj,
((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);
diff --git a/libexec/rtld-elf/powerpc64/rtld_machdep.h b/libexec/rtld-elf/powerpc64/rtld_machdep.h
index 90253d7..a0fed7f 100644
--- a/libexec/rtld-elf/powerpc64/rtld_machdep.h
+++ b/libexec/rtld-elf/powerpc64/rtld_machdep.h
@@ -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)
diff --git a/libexec/rtld-elf/riscv/reloc.c b/libexec/rtld-elf/riscv/reloc.c
index 71259cd..a0fedf1 100644
--- a/libexec/rtld-elf/riscv/reloc.c
+++ b/libexec/rtld-elf/riscv/reloc.c
@@ -226,10 +226,9 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr target, const Obj_Entry *defobj,
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);
}
/*
diff --git a/libexec/rtld-elf/riscv/rtld_machdep.h b/libexec/rtld-elf/riscv/rtld_machdep.h
index 4fb4947..95669ff 100644
--- a/libexec/rtld-elf/riscv/rtld_machdep.h
+++ b/libexec/rtld-elf/riscv/rtld_machdep.h
@@ -54,9 +54,8 @@ uint64_t set_gp(struct Struct_Obj_Entry *obj);
})
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)
diff --git a/libexec/rtld-elf/rtld.1 b/libexec/rtld-elf/rtld.1
index a8e9d68..79f1478 100644
--- a/libexec/rtld-elf/rtld.1
+++ b/libexec/rtld-elf/rtld.1
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 20, 2014
+.Dd March 16, 2017
.Dt RTLD 1
.Os
.Sh NAME
@@ -199,6 +199,13 @@ 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.
+This variable is unset for set-user-ID and set-group-ID programs.
.It Ev LD_BIND_NOW
When set to a nonempty string, causes
.Nm
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index a3def35..25d5970 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -178,6 +178,7 @@ static char *libmap_override; /* Maps to use in addition to libmap.conf */
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,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
md_abi_variant_hook(aux_info);
ld_bind_now = getenv(_LD("BIND_NOW"));
+
/*
* If the process is tainted, then we un-set the dangerous environment
* variables. The process will be marked as tainted until setuid(2)
@@ -425,7 +427,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
if (!trust) {
if (unsetenv(_LD("PRELOAD")) || unsetenv(_LD("LIBMAP")) ||
unsetenv(_LD("LIBRARY_PATH")) || unsetenv(_LD("LIBRARY_PATH_FDS")) ||
- unsetenv(_LD("LIBMAP_DISABLE")) ||
+ unsetenv(_LD("LIBMAP_DISABLE")) || unsetenv(_LD("BIND_NOT")) ||
unsetenv(_LD("DEBUG")) || unsetenv(_LD("ELF_HINTS_PATH")) ||
unsetenv(_LD("LOADFLTR")) || unsetenv(_LD("LIBRARY_PATH_RPATH"))) {
_rtld_error("environment corrupt; aborting");
@@ -433,6 +435,8 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
}
}
ld_debug = getenv(_LD("DEBUG"));
+ if (ld_bind_now == NULL)
+ ld_bind_not = getenv(_LD("BIND_NOT")) != NULL;
libmap_disable = getenv(_LD("LIBMAP_DISABLE")) != NULL;
libmap_override = getenv(_LD("LIBMAP"));
ld_library_path = getenv(_LD("LIBRARY_PATH"));
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
index 4e48026..19fb8fc 100644
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -358,6 +358,7 @@ void *malloc_aligned(size_t size, size_t align);
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 *);
diff --git a/libexec/rtld-elf/sparc64/reloc.c b/libexec/rtld-elf/sparc64/reloc.c
index 197c66c..108af80 100644
--- a/libexec/rtld-elf/sparc64/reloc.c
+++ b/libexec/rtld-elf/sparc64/reloc.c
@@ -581,7 +581,9 @@ reloc_jmpslot(Elf_Addr *wherep, Elf_Addr target, const Obj_Entry *obj,
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
diff --git a/libexec/rtld-elf/sparc64/rtld_machdep.h b/libexec/rtld-elf/sparc64/rtld_machdep.h
index 6e86e65..5266f8b 100644
--- a/libexec/rtld-elf/sparc64/rtld_machdep.h
+++ b/libexec/rtld-elf/sparc64/rtld_machdep.h
@@ -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)
OpenPOWER on IntegriCloud