Commit 6fc06960 authored by Shawn Webb's avatar Shawn Webb Committed by Oliver Pinter
Browse files

HBSD: Randomize shared object loading order in rtld

HBSD: Randomize shared object loading order

This is just phase 1 (proof of concept) of shared object loading order
randomization. Cleanup and performance enhancements along with major
testing needed in order to consider this code production-ready.

github-issue: #89
(cherry picked from commit b3005589)

Randomize Shared Object Loading Order

github-issue: #89
Refactor code. Clean it up and make it perform better. Tested on a full
amd64 install, complete with Xorg, xfce4, and Chromium. All works
perfectly, albeit with slightly more lag. Further performance
enhancements ought to be researched.

(cherry picked from commit 0159afbe

)
Signed-off-by: Shawn Webb's avatarShawn Webb <shawn.webb@hardenedbsd.org>
Signed-off-by: default avatarOliver Pinter <oliver.pinter@hardenedbsd.org>

HBSD: follow rtld's braindamage coding style..
Signed-off-by: default avatarOliver Pinter <oliver.pinter@hardenedbsd.org>
parent ed5f41fe
......@@ -105,6 +105,7 @@ static void linkmap_add(Obj_Entry *);
static void linkmap_delete(Obj_Entry *);
static void load_filtees(Obj_Entry *, int flags, RtldLockState *);
static void unload_filtees(Obj_Entry *);
static void randomize_neededs(Obj_Entry *obj, int flags);
static int load_needed_objects(Obj_Entry *, int);
static int load_preload_objects(void);
static Obj_Entry *load_object(const char *, int fd, const Obj_Entry *, int);
......@@ -2028,14 +2029,66 @@ process_needed(Obj_Entry *obj, Needed_Entry *needed, int flags)
Obj_Entry *obj1;
for (; needed != NULL; needed = needed->next) {
dbg("%s: %s requires %s.",
__func__, obj->path ? obj->path : "[nopath]",
obj->strtab + needed->name);
obj1 = needed->obj = load_object(obj->strtab + needed->name, -1, obj,
flags & ~RTLD_LO_NOLOAD);
if (obj1 == NULL && !ld_tracing && (flags & RTLD_LO_FILTEES) == 0)
if (obj1 == NULL && !ld_tracing && (flags & RTLD_LO_FILTEES) == 0) {
return (-1);
}
}
return (0);
}
static void
randomize_neededs(Obj_Entry *obj, int flags)
{
Needed_Entry **needs=NULL, *need=NULL;
unsigned int i, j, nneed;
size_t sz = sizeof(unsigned int);
int mib[2];
if (!(obj->needed) || (flags & RTLD_LO_FILTEES))
return;
mib[0] = CTL_KERN;
mib[1] = KERN_ARND;
for (nneed = 0, need = obj->needed; need != NULL; need = need->next)
nneed++;
if (nneed > 1) {
needs = xcalloc(nneed, sizeof(Needed_Entry **));
for (i = 0, need = obj->needed; i < nneed; i++, need = need->next)
needs[i] = need;
for (i=0; i < nneed; i++) {
do {
if (sysctl(mib, 2, &j, &sz, NULL, 0))
goto err;
j %= nneed;
} while (j == i);
need = needs[i];
needs[i] = needs[j];
needs[j] = need;
}
for (i=0; i < nneed; i++)
needs[i]->next = i + 1 < nneed ? needs[i + 1] : NULL;
obj->needed = needs[0];
}
err:
if (needs != NULL)
free(needs);
return;
}
/*
* Given a shared object, traverse its list of needed objects, and load
* each of them. Returns 0 on success. Generates an error message and
......@@ -2044,13 +2097,15 @@ process_needed(Obj_Entry *obj, Needed_Entry *needed, int flags)
static int
load_needed_objects(Obj_Entry *first, int flags)
{
Obj_Entry *obj;
Obj_Entry *obj;
for (obj = first; obj != NULL; obj = obj->next) {
if (process_needed(obj, obj->needed, flags) == -1)
return (-1);
}
return (0);
for (obj = first; obj != NULL; obj = obj->next) {
randomize_neededs(obj, flags);
if (process_needed(obj, obj->needed, flags) == -1)
return (-1);
}
return (0);
}
static int
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment