From 62af2dc3fbb213db3bd221b28ceb726106d6150a Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 22 Apr 2020 18:39:45 +0000 Subject: [PATCH] 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 --- libexec/rtld-elf/rtld.c | 8 ++++---- libexec/rtld-elf/rtld.h | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 622d8d373a0..4b26aefb524 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -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 *refobj, int lo_flags, /* 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) diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h index a8f26cea1f9..7812ebb1539 100644 --- a/libexec/rtld-elf/rtld.h +++ b/libexec/rtld-elf/rtld.h @@ -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