For the main binary, postpone enforcing relro read-only protection

until copy relocations are done.

Newer binutils and lld seems to output copy into relro-protected range.

Reported by: Rafael Espц╜ndola via emaste
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This commit is contained in:
kib 2017-01-12 15:54:03 +00:00
parent ce74585957
commit 355a081d90

View File

@ -103,6 +103,7 @@ static int load_needed_objects(Obj_Entry *, int);
static int load_preload_objects(void); static int load_preload_objects(void);
static Obj_Entry *load_object(const char *, int fd, const Obj_Entry *, int); static Obj_Entry *load_object(const char *, int fd, const Obj_Entry *, int);
static void map_stacks_exec(RtldLockState *); static void map_stacks_exec(RtldLockState *);
static int obj_enforce_relro(Obj_Entry *);
static Obj_Entry *obj_from_addr(const void *); static Obj_Entry *obj_from_addr(const void *);
static void objlist_call_fini(Objlist *, Obj_Entry *, RtldLockState *); static void objlist_call_fini(Objlist *, Obj_Entry *, RtldLockState *);
static void objlist_call_init(Objlist *, RtldLockState *); static void objlist_call_init(Objlist *, RtldLockState *);
@ -617,6 +618,10 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
if (do_copy_relocations(obj_main) == -1) if (do_copy_relocations(obj_main) == -1)
rtld_die(); rtld_die();
dbg("enforcing main obj relro");
if (obj_enforce_relro(obj_main) == -1)
rtld_die();
if (getenv(_LD("DUMP_REL_POST")) != NULL) { if (getenv(_LD("DUMP_REL_POST")) != NULL) {
dump_relocations(obj_main); dump_relocations(obj_main);
exit (0); exit (0);
@ -2746,14 +2751,8 @@ relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj,
reloc_non_plt(obj, rtldobj, flags | SYMLOOK_IFUNC, lockstate)) reloc_non_plt(obj, rtldobj, flags | SYMLOOK_IFUNC, lockstate))
return (-1); return (-1);
if (obj->relro_size > 0) { if (!obj->mainprog && obj_enforce_relro(obj) == -1)
if (mprotect(obj->relro_page, obj->relro_size, return (-1);
PROT_READ) == -1) {
_rtld_error("%s: Cannot enforce relro protection: %s",
obj->path, rtld_strerror(errno));
return (-1);
}
}
/* /*
* Set up the magic number and version in the Obj_Entry. These * Set up the magic number and version in the Obj_Entry. These
@ -5124,6 +5123,19 @@ _rtld_is_dlopened(void *arg)
return (res); return (res);
} }
int
obj_enforce_relro(Obj_Entry *obj)
{
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));
return (-1);
}
return (0);
}
static void static void
map_stacks_exec(RtldLockState *lockstate) map_stacks_exec(RtldLockState *lockstate)
{ {