block dlopen of libraries with initial-exec refs to dynamic TLS
authorRich Felker <dalias@aerifal.cx>
Mon, 16 Jul 2018 16:32:57 +0000 (12:32 -0400)
committerRich Felker <dalias@aerifal.cx>
Mon, 16 Jul 2018 16:32:57 +0000 (12:32 -0400)
previously, this operation succeeded, and the relocation results
worked for access from new threads created after dlopen, but produced
invalid accesses (and possibly clobbered other memory) from threads
that already existed.

the way the check is written, it still permits dlopen of libraries
containing initial-exec references to static TLS (TLS in the main
program or in a dynamic library loaded at startup).

ldso/dynlink.c

index 8242a1d1aba7f3005a46b5401954bedae7a10864..87281ddb6fef7e47d17b98c2846a2971c8f08cc1 100644 (file)
@@ -385,6 +385,14 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
                sym_val = def.sym ? (size_t)laddr(def.dso, def.sym->st_value) : 0;
                tls_val = def.sym ? def.sym->st_value : 0;
 
+               if ((type == REL_TPOFF || type == REL_TPOFF_NEG)
+                   && runtime && def.dso->tls_id > static_tls_cnt) {
+                       error("Error relocating %s: %s: initial-exec TLS "
+                               "resolves to dynamic definition in %s",
+                               dso->name, name, def.dso->name);
+                       longjmp(*rtld_fail, 1);
+               }
+
                switch(type) {
                case REL_NONE:
                        break;