git: 7cb32a0d0343 - main - rtld: avoid recursing on rtld_bind_lock for write

Konstantin Belousov kib at FreeBSD.org
Fri Apr 9 20:47:18 UTC 2021


The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=7cb32a0d03437f881169b1c55cce89cf70ed43dd

commit 7cb32a0d03437f881169b1c55cce89cf70ed43dd
Author:     Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2021-04-06 19:02:23 +0000
Commit:     Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2021-04-09 20:46:24 +0000

    rtld: avoid recursing on rtld_bind_lock for write
    
    This fixes a regression in d36d6816151705907393889, where the call to
    __tls_get_address() was performed under rtld_bind_lock write-locked.
    Instead use tls_get_addr_slow() directly, with locked = true.
    
    Reported by:    jkim, many others
    Tested by:      jkim, bdragon (powerpc), mhorne (riscv)
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D29623
---
 libexec/rtld-elf/rtld-libc/Makefile.inc | 2 ++
 libexec/rtld-elf/rtld.c                 | 8 ++++----
 libexec/rtld-elf/rtld.h                 | 1 +
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/libexec/rtld-elf/rtld-libc/Makefile.inc b/libexec/rtld-elf/rtld-libc/Makefile.inc
index d5f5993e3f16..7ffcb6e41ec7 100644
--- a/libexec/rtld-elf/rtld-libc/Makefile.inc
+++ b/libexec/rtld-elf/rtld-libc/Makefile.inc
@@ -67,6 +67,8 @@ _libc_other_objects+=syncicache abs
 _libc_other_objects+=syncicache
 .endif
 
+_libc_other_objects+=_get_tp
+
 # Extract all the .o files from libc_nossp_pic.a. This ensures that
 # we don't accidentally pull in the interposing table or similar by linking
 # directly against libc_nossp_pic.a
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 8c8271abc93e..29ab4e93d4da 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -3910,16 +3910,16 @@ dlinfo(void *handle, int request, void *p)
 static void
 rtld_fill_dl_phdr_info(const Obj_Entry *obj, struct dl_phdr_info *phdr_info)
 {
-	tls_index ti;
+	Elf_Addr **dtvp;
 
 	phdr_info->dlpi_addr = (Elf_Addr)obj->relocbase;
 	phdr_info->dlpi_name = obj->path;
 	phdr_info->dlpi_phdr = obj->phdr;
 	phdr_info->dlpi_phnum = obj->phsize / sizeof(obj->phdr[0]);
 	phdr_info->dlpi_tls_modid = obj->tlsindex;
-	ti.ti_module = obj->tlsindex;
-	ti.ti_offset = 0;
-	phdr_info->dlpi_tls_data = __tls_get_addr(&ti);
+	dtvp = _get_tp();
+	phdr_info->dlpi_tls_data = (char *)tls_get_addr_slow(dtvp,
+	    obj->tlsindex, 0, true) + TLS_DTV_OFFSET;
 	phdr_info->dlpi_adds = obj_loads;
 	phdr_info->dlpi_subs = obj_loads - obj_count;
 }
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
index 85472826a4ec..6a2f62fc6189 100644
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -401,6 +401,7 @@ bool allocate_tls_offset(Obj_Entry *obj);
 void free_tls_offset(Obj_Entry *obj);
 const Ver_Entry *fetch_ventry(const Obj_Entry *obj, unsigned long);
 int convert_prot(int elfflags);
+void *_get_tp(void);	/* libc implementation */
 
 /*
  * MD function declarations.


More information about the dev-commits-src-all mailing list