Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Apr 2020 18:39:45 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r360201 - head/libexec/rtld-elf
Message-ID:  <202004221839.03MIdj0K063249@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Wed Apr 22 18:39:45 2020
New Revision: 360201
URL: https://svnweb.freebsd.org/changeset/base/360201

Log:
  rtld: ignore static TLS segments when tracing.
  
  For PIE binaries, ldd(1) performs dlopen(RTLD_TRACE) on the binary.
  It is legal for binary to use initial exec TLS mode, but when such
  binary (actually dso) is dlopened, we might not have enough free space
  in the finalized static TLS segment.  Make ldd operational by skipping
  TLS space allocation, we are not going to execute any code from the
  dso anyway.
  
  Reported by:	tobik
  PR:	245677
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/libexec/rtld-elf/rtld.c
  head/libexec/rtld-elf/rtld.h

Modified: head/libexec/rtld-elf/rtld.c
==============================================================================
--- head/libexec/rtld-elf/rtld.c	Wed Apr 22 17:14:02 2020	(r360200)
+++ head/libexec/rtld-elf/rtld.c	Wed Apr 22 18:39:45 2020	(r360201)
@@ -3367,7 +3367,7 @@ rtld_dlopen(const char *name, int fd, int mode)
     if (mode & RTLD_NOLOAD)
 	    lo_flags |= RTLD_LO_NOLOAD;
     if (ld_tracing != NULL)
-	    lo_flags |= RTLD_LO_TRACE;
+	    lo_flags |= RTLD_LO_TRACE | RTLD_LO_IGNSTLS;
 
     return (dlopen_object(name, fd, obj_main, lo_flags,
       mode & (RTLD_MODEMASK | RTLD_GLOBAL), NULL));
@@ -3418,15 +3418,15 @@ dlopen_object(const char *name, int fd, Obj_Entry *ref
 	    /* We loaded something new. */
 	    assert(globallist_next(old_obj_tail) == obj);
 	    result = 0;
-	    if ((lo_flags & RTLD_LO_EARLY) == 0 && obj->static_tls &&
-	      !allocate_tls_offset(obj)) {
+	    if ((lo_flags & (RTLD_LO_EARLY | RTLD_LO_IGNSTLS)) == 0 &&
+	      obj->static_tls && !allocate_tls_offset(obj)) {
 		_rtld_error("%s: No space available "
 		  "for static Thread Local Storage", obj->path);
 		result = -1;
 	    }
 	    if (result != -1)
 		result = load_needed_objects(obj, lo_flags & (RTLD_LO_DLOPEN |
-		    RTLD_LO_EARLY));
+		    RTLD_LO_EARLY | RTLD_LO_IGNSTLS));
 	    init_dag(obj);
 	    ref_dag(obj);
 	    if (result != -1)

Modified: head/libexec/rtld-elf/rtld.h
==============================================================================
--- head/libexec/rtld-elf/rtld.h	Wed Apr 22 17:14:02 2020	(r360200)
+++ head/libexec/rtld-elf/rtld.h	Wed Apr 22 18:39:45 2020	(r360201)
@@ -308,6 +308,7 @@ TAILQ_HEAD(obj_entry_q, Struct_Obj_Entry);
 #define	RTLD_LO_FILTEES 0x10	/* Loading filtee. */
 #define	RTLD_LO_EARLY	0x20	/* Do not call ctors, postpone it to the
 				   initialization during the image start. */
+#define	RTLD_LO_IGNSTLS 0x40	/* Do not allocate static TLS */
 
 /*
  * Symbol cache entry used during relocation to avoid multiple lookups



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202004221839.03MIdj0K063249>