git: d36d68161517 - main - rtld dl_iterate_phdr(): dlpi_tls_data is wrong

Konstantin Belousov kib at FreeBSD.org
Tue Apr 6 00:37:20 UTC 2021


The branch main has been updated by kib:

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

commit d36d6816151705907393889d661cbfd25c630ca8
Author:     Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2021-04-05 03:05:44 +0000
Commit:     Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2021-04-06 00:23:08 +0000

    rtld dl_iterate_phdr(): dlpi_tls_data is wrong
    
    dl_iterate_phdr() dlpi_tls_data should provide the TLS module segment
    address, and not the TLS init segment address as it does now.
    
    Reported by:    emacsray at gmail.com
    PR:     254774
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
---
 lib/libc/gen/dl_iterate_phdr.3 | 7 +++++--
 libexec/rtld-elf/Symbol.map    | 1 +
 libexec/rtld-elf/rtld.1        | 7 +++++++
 libexec/rtld-elf/rtld.c        | 8 +++++++-
 sys/sys/param.h                | 2 +-
 5 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/lib/libc/gen/dl_iterate_phdr.3 b/lib/libc/gen/dl_iterate_phdr.3
index 6e952dc13b57..fe4face9eeb7 100644
--- a/lib/libc/gen/dl_iterate_phdr.3
+++ b/lib/libc/gen/dl_iterate_phdr.3
@@ -15,7 +15,7 @@
 .\"
 .\"   $OpenBSD: dl_iterate_phdr.3,v 1.3 2007/05/31 19:19:48 jmc Exp $
 .\" $FreeBSD$
-.Dd October 9, 2014
+.Dd April 5, 2021
 .Dt DL_ITERATE_PHDR 3
 .Os
 .Sh NAME
@@ -80,7 +80,10 @@ The counter of the object unloads performed by the dynamic linker.
 .It Fa dlpi_tls_modid
 The TLS index of the object.
 .It Fa dlpi_tls_data
-A pointer to the initialization data for the object TLS segment.
+A pointer to the calling thread' TLS data segment for this module,
+if it was allocated,
+.Dv NULL
+otherwise.
 .El
 .Pp
 Future versions of
diff --git a/libexec/rtld-elf/Symbol.map b/libexec/rtld-elf/Symbol.map
index 13068c5626dc..0a9eac82cf05 100644
--- a/libexec/rtld-elf/Symbol.map
+++ b/libexec/rtld-elf/Symbol.map
@@ -34,4 +34,5 @@ FBSDprivate_1.0 {
     _r_debug_postinit;
     _rtld_version__FreeBSD_version;
     _rtld_version_laddr_offset;
+    _rtld_version_dlpi_tls_data;
 };
diff --git a/libexec/rtld-elf/rtld.1 b/libexec/rtld-elf/rtld.1
index 589b9a92aa77..7f633ce0b486 100644
--- a/libexec/rtld-elf/rtld.1
+++ b/libexec/rtld-elf/rtld.1
@@ -424,6 +424,13 @@ See
 Also it indicates the presence of
 .Va l_refname
 member of the structure.
+.It Dv _rtld_version_dlpi_tls_data
+The
+.Va dlpi_tls_data
+member of the structure
+.Vt dl_phdr_info
+contains the address of the module TLS segment for the calling thread,
+and not the address of the initialization segment.
 .El
 .Sh FILES
 .Bl -tag -width ".Pa /var/run/ld-elf32.so.hints" -compact
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 733c3c80b70f..19027518d3c2 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -3909,13 +3909,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;
 
 	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;
-	phdr_info->dlpi_tls_data = obj->tlsinit;
+	ti.ti_module = obj->tlsindex;
+	ti.ti_offset = 0;
+	phdr_info->dlpi_tls_data = __tls_get_addr(&ti);
 	phdr_info->dlpi_adds = obj_loads;
 	phdr_info->dlpi_subs = obj_loads - obj_count;
 }
@@ -5914,3 +5917,6 @@ int _rtld_version__FreeBSD_version = __FreeBSD_version;
 
 extern char _rtld_version_laddr_offset __exported;
 char _rtld_version_laddr_offset;
+
+extern char _rtld_version_dlpi_tls_data __exported;
+char _rtld_version_dlpi_tls_data;
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 5176dd1e9732..e3230de27bb1 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -60,7 +60,7 @@
  *		in the range 5 to 9.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 1400006	/* Master, propagated to newvers */
+#define __FreeBSD_version 1400007	/* Master, propagated to newvers */
 
 /*
  * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,


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