Page MenuHomeFreeBSD

D18400.diff
No OneTemporary

D18400.diff

Index: head/libexec/rtld-elf/rtld.h
===================================================================
--- head/libexec/rtld-elf/rtld.h
+++ head/libexec/rtld-elf/rtld.h
@@ -264,6 +264,7 @@
bool irelative : 1; /* Object has R_MACHDEP_IRELATIVE relocs */
bool gnu_ifunc : 1; /* Object has references to STT_GNU_IFUNC */
bool non_plt_gnu_ifunc : 1; /* Object has non-plt IFUNC references */
+ bool ifuncs_resolved : 1; /* Object ifuncs were already resolved */
bool crt_no_init : 1; /* Object' crt does not call _init/_fini */
bool valid_hash_sysv : 1; /* A valid System V hash hash tag is available */
bool valid_hash_gnu : 1; /* A valid GNU hash tag is available */
Index: head/libexec/rtld-elf/rtld.c
===================================================================
--- head/libexec/rtld-elf/rtld.c
+++ head/libexec/rtld-elf/rtld.c
@@ -111,6 +111,7 @@
static void init_rtld(caddr_t, Elf_Auxinfo **);
static void initlist_add_neededs(Needed_Entry *, Objlist *);
static void initlist_add_objects(Obj_Entry *, Obj_Entry *, Objlist *);
+static int initlist_objects_ifunc(Objlist *, bool, int, RtldLockState *);
static void linkmap_add(Obj_Entry *);
static void linkmap_delete(Obj_Entry *);
static void load_filtees(Obj_Entry *, int flags, RtldLockState *);
@@ -119,6 +120,7 @@
static int load_preload_objects(void);
static Obj_Entry *load_object(const char *, int fd, const Obj_Entry *, int);
static void map_stacks_exec(RtldLockState *);
+static int obj_disable_relro(Obj_Entry *);
static int obj_enforce_relro(Obj_Entry *);
static Obj_Entry *obj_from_addr(const void *);
static void objlist_call_fini(Objlist *, Obj_Entry *, RtldLockState *);
@@ -143,8 +145,6 @@
static int relocate_objects(Obj_Entry *, bool, Obj_Entry *, int,
RtldLockState *);
static int resolve_object_ifunc(Obj_Entry *, bool, int, RtldLockState *);
-static int resolve_objects_ifunc(Obj_Entry *first, bool bind_now,
- int flags, RtldLockState *lockstate);
static int rtld_dirname(const char *, char *);
static int rtld_dirname_abs(const char *, char *);
static void *rtld_dlopen(const char *name, int fd, int mode);
@@ -730,16 +730,6 @@
map_stacks_exec(NULL);
- dbg("resolving ifuncs");
- if (resolve_objects_ifunc(obj_main,
- ld_bind_now != NULL && *ld_bind_now != '\0', SYMLOOK_EARLY,
- NULL) == -1)
- rtld_die();
-
- dbg("enforcing main obj relro");
- if (obj_enforce_relro(obj_main) == -1)
- rtld_die();
-
if (!obj_main->crt_no_init) {
/*
* Make sure we don't call the main program's init and fini
@@ -758,6 +748,12 @@
pre_init();
wlock_acquire(rtld_bind_lock, &lockstate);
+
+ dbg("resolving ifuncs");
+ if (initlist_objects_ifunc(&initlist, ld_bind_now != NULL &&
+ *ld_bind_now != '\0', SYMLOOK_EARLY, &lockstate) == -1)
+ rtld_die();
+
if (obj_main->crt_no_init)
preinit_main();
objlist_call_init(&initlist, &lockstate);
@@ -770,6 +766,11 @@
if (ld_loadfltr || obj->z_loadfltr)
load_filtees(obj, 0, &lockstate);
}
+
+ dbg("enforcing main obj relro");
+ if (obj_enforce_relro(obj_main) == -1)
+ rtld_die();
+
lock_release(rtld_bind_lock, &lockstate);
dbg("transferring control to program entry point = %p", obj_main->entry);
@@ -2243,9 +2244,7 @@
initlist_add_neededs(obj->needed_aux_filtees, list);
/* Add the object to the init list. */
- if (obj->preinit_array != (Elf_Addr)NULL || obj->init != (Elf_Addr)NULL ||
- obj->init_array != (Elf_Addr)NULL)
- objlist_push_tail(list, obj);
+ objlist_push_tail(list, obj);
/* Add the object to the global fini list in the reverse order. */
if ((obj->fini != (Elf_Addr)NULL || obj->fini_array != (Elf_Addr)NULL)
@@ -2894,11 +2893,9 @@
if (reloc_plt(obj) == -1)
return (-1);
/* Relocate the jump slots if we are doing immediate binding. */
- if (obj->bind_now || bind_now) {
- if (reloc_jmpslots(obj, flags, lockstate) == -1 ||
- resolve_object_ifunc(obj, true, flags, lockstate) == -1)
- return (-1);
- }
+ if ((obj->bind_now || bind_now) && reloc_jmpslots(obj, flags,
+ lockstate) == -1)
+ return (-1);
/*
* Process the non-PLT IFUNC relocations. The relocations are
@@ -2964,24 +2961,16 @@
resolve_object_ifunc(Obj_Entry *obj, bool bind_now, int flags,
RtldLockState *lockstate)
{
+
+ if (obj->ifuncs_resolved)
+ return (0);
+ obj->ifuncs_resolved = true;
if (obj->irelative && reloc_iresolve(obj, lockstate) == -1)
return (-1);
- if ((obj->bind_now || bind_now) && obj->gnu_ifunc &&
- reloc_gnu_ifunc(obj, flags, lockstate) == -1)
- return (-1);
- return (0);
-}
-
-static int
-resolve_objects_ifunc(Obj_Entry *first, bool bind_now, int flags,
- RtldLockState *lockstate)
-{
- Obj_Entry *obj;
-
- for (obj = first; obj != NULL; obj = TAILQ_NEXT(obj, next)) {
- if (obj->marker)
- continue;
- if (resolve_object_ifunc(obj, bind_now, flags, lockstate) == -1)
+ if ((obj->bind_now || bind_now) && obj->gnu_ifunc) {
+ if (obj_disable_relro(obj) ||
+ reloc_gnu_ifunc(obj, flags, lockstate) == -1 ||
+ obj_enforce_relro(obj))
return (-1);
}
return (0);
@@ -2992,9 +2981,13 @@
RtldLockState *lockstate)
{
Objlist_Entry *elm;
+ Obj_Entry *obj;
STAILQ_FOREACH(elm, list, link) {
- if (resolve_object_ifunc(elm->obj, bind_now, flags,
+ obj = elm->obj;
+ if (obj->marker)
+ continue;
+ if (resolve_object_ifunc(obj, bind_now, flags,
lockstate) == -1)
return (-1);
}
@@ -5354,17 +5347,31 @@
return (res);
}
-int
-obj_enforce_relro(Obj_Entry *obj)
+static int
+obj_remap_relro(Obj_Entry *obj, int prot)
{
if (obj->relro_size > 0 && mprotect(obj->relro_page, obj->relro_size,
- PROT_READ) == -1) {
- _rtld_error("%s: Cannot enforce relro protection: %s",
- obj->path, rtld_strerror(errno));
+ prot) == -1) {
+ _rtld_error("%s: Cannot set relro protection to %#x: %s",
+ obj->path, prot, rtld_strerror(errno));
return (-1);
}
return (0);
+}
+
+static int
+obj_disable_relro(Obj_Entry *obj)
+{
+
+ return (obj_remap_relro(obj, PROT_READ | PROT_WRITE));
+}
+
+static int
+obj_enforce_relro(Obj_Entry *obj)
+{
+
+ return (obj_remap_relro(obj, PROT_READ));
}
static void

File Metadata

Mime Type
text/plain
Expires
Thu, Feb 13, 1:16 AM (20 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16620213
Default Alt Text
D18400.diff (6 KB)

Event Timeline