Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID:
 <BN0SPR01MB00023DB344ABAA7F6D553E88B9FD2@BN0SPR01MB0002.namprd20.prod.outlook.com>
Date: Tue, 11 Feb 2025 19:50:40 +0000
From: Daniil Kovalev <dkovalev@...esssoftek.com>
To: "musl@...ts.openwall.com" <musl@...ts.openwall.com>
Subject: [PATCH] aarch64: handle TLSDESC relocs against undef weak symbols

if a weak symbol is undefined, it's address must be null. when accessing
a thread-local symbol via tlsdesc, the value of TPIDR_EL0 is added to the
return value of the tls descriptor function. so, in case of an undefined
symbol, the descriptor function should return -TPIDR_EL0 which will give
null after adding TPIDR_EL0.
---
 arch/aarch64/reloc.h       | 2 ++
 ldso/dynlink.c             | 6 ++++++
 src/internal/dynlink.h     | 3 +++
 src/ldso/aarch64/tlsdesc.s | 9 +++++++++
 4 files changed, 20 insertions(+)

diff --git a/arch/aarch64/reloc.h b/arch/aarch64/reloc.h
index b1b68c72..a8229982 100644
--- a/arch/aarch64/reloc.h
+++ b/arch/aarch64/reloc.h
@@ -20,5 +20,7 @@
 #define REL_TPOFF       R_AARCH64_TLS_TPREL64
 #define REL_TLSDESC     R_AARCH64_TLSDESC
 
+#define TLSDESC_UNDEF_WEAK_SUPPORT 1
+
 #define CRTJMP(pc,sp) __asm__ __volatile__( \
 	"mov sp,%1 ; br %0" : : "r"(pc), "r"(sp) : "memory" )
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 3b57c07f..4b19ef0d 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -515,6 +515,12 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
 #endif
 		case REL_TLSDESC:
 			if (stride<3) addend = reloc_addr[!TLSDESC_BACKWARDS];
+#ifdef TLSDESC_UNDEF_WEAK_SUPPORT
+			if (sym && sym->st_info>>4 == STB_WEAK && sym->st_shndx == SHN_UNDEF) {
+				reloc_addr[0] = (size_t)__tlsdesc_undef_weak;
+				reloc_addr[1] = 0;
+			} else
+#endif
 			if (def.dso->tls_id > static_tls_cnt) {
 				struct td_index *new = malloc(sizeof *new);
 				if (!new) {
diff --git a/src/internal/dynlink.h b/src/internal/dynlink.h
index 40c743e2..588458f3 100644
--- a/src/internal/dynlink.h
+++ b/src/internal/dynlink.h
@@ -112,6 +112,9 @@ hidden int __dl_invalid_handle(void *);
 hidden void __dl_vseterr(const char *, va_list);
 
 hidden ptrdiff_t __tlsdesc_static(), __tlsdesc_dynamic();
+#ifdef TLSDESC_UNDEF_WEAK_SUPPORT
+hidden ptrdiff_t __tlsdesc_undef_weak();
+#endif
 
 hidden extern int __malloc_replaced;
 hidden extern int __aligned_alloc_replaced;
diff --git a/src/ldso/aarch64/tlsdesc.s b/src/ldso/aarch64/tlsdesc.s
index c6c685b3..e4b0f9a6 100644
--- a/src/ldso/aarch64/tlsdesc.s
+++ b/src/ldso/aarch64/tlsdesc.s
@@ -29,3 +29,12 @@ __tlsdesc_dynamic:
 	add x0,x1,x2          // dtv[p->modidx] + p->off - tp
 	ldp x1,x2,[sp],#16
 	ret
+
+.global __tlsdesc_undef_weak
+.hidden __tlsdesc_undef_weak
+.type __tlsdesc_undef_weak,@function
+__tlsdesc_undef_weak:
+	mov x0,#0
+	mrs x8,TPIDR_EL0
+	sub x0,x0,x8
+	ret
-- 
2.48.1


Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.