rtld - Fix ifunc relocations
authorMatthew Dillon <dillon@apollo.backplane.com>
Tue, 5 Dec 2017 08:14:20 +0000 (00:14 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Tue, 5 Dec 2017 08:14:20 +0000 (00:14 -0800)
* ifunc relocations had a bug that caused an immediate seg-fault.
  Apparently this type of relocation is not used very much, we've
  never encountered it before.  But the qemu port uses it.

* Fix the bug.  Basically missing lockstate and the top level in
  rtld was expected to hold the bind lock.

libexec/rtld-elf/rtld.c

index 16d5ba7..1680ab1 100644 (file)
@@ -674,10 +674,19 @@ resident_skip2:
     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)
-       die();
+    {
+           RtldLockState lockstate;
+
+           wlock_acquire(rtld_bind_lock, &lockstate);
+           if (resolve_objects_ifunc(
+                   obj_main,
+                   (ld_bind_now != NULL && *ld_bind_now != '\0'),
+                   SYMLOOK_EARLY,
+                   &lockstate) == -1) {
+                   die();
+           }
+           lock_release(rtld_bind_lock, &lockstate);
+    }
 
     /*
      * Do NOT call the initlist here, give libc a chance to set up