aboutsummaryrefslogtreecommitdiff
path: root/libexec/rtld-elf
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2018-11-20 14:52:43 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2018-11-20 14:52:43 +0000
commitabfc3b2fef13ff0cd1bc061c11629ecbf4912e6f (patch)
tree29b3810bceb18e70a163a75d34478f318431682b /libexec/rtld-elf
parent7df0e7beb7417750db24cc1eb342a3cd0f133ef5 (diff)
downloadsrc-abfc3b2fef13ff0cd1bc061c11629ecbf4912e6f.tar.gz
src-abfc3b2fef13ff0cd1bc061c11629ecbf4912e6f.zip
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
Notes
Notes: svn path=/head/; revision=340675
Diffstat (limited to 'libexec/rtld-elf')
-rw-r--r--libexec/rtld-elf/rtld.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 393afff2d66a..b78dc84fe310 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -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