rtld: when immediate bind mode is requested, process irelocs in PLT

immediately after other PLT relocs.

Otherwise, if the object has relro page, we write to readonly page,
and we would need to use mprotect(2) two more times to fix it.  Note
that resolve_object_ifunc() does nothing when called second time, so
there is no need to avoid existing call.

Reported and tested by:	emaste
PR:	233333
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2018-11-20 14:52:43 +00:00
parent 7df0e7beb7
commit abfc3b2fef

View file

@ -142,6 +142,7 @@ static int relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj,
int flags, RtldLockState *lockstate);
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 *);
@ -2885,9 +2886,11 @@ relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj,
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)
if (obj->bind_now || bind_now) {
if (reloc_jmpslots(obj, flags, lockstate) == -1 ||
resolve_object_ifunc(obj, true, flags, lockstate) == -1)
return (-1);
}
/*
* Process the non-PLT IFUNC relocations. The relocations are