Fix interactions of initial-exec TLS model and dlopen

(1) If an initial-exec relocation was used for a non-local symbol
(i.e. the definition of the symbol is in a different DSO), the
computation of the static TLS offset used the wrong DSO.
This would effectively mean the wrong address was computed
(PR toolchain/50277, PR pkg/57445).

Fix this by forcing the computation of the correct DSO (the one defining
the symbol).

This code uses __UNCONST to avoid the vast interface changes for this
special case.

(2) If symbols from a DSO loaded via dlopen are used with both
global-dynamic/local-dynamic and initial-exec relocations AND
a initial-exec relocation was resolved first in a thread, a split brain
situation could exist where the dynamic relocations would use one memory
block (separate allocation) and the initial-exec relocations the static
per-thread TLS space.

(3) If the initial-exec relocation in (2) is seen after any thread has
already used a GD/LD allocation, bail out. Since IE relocations are used
only in the GOT, this will prevent the dlopen. This is a bit more
aggressive than necessary, but a full blown reference counting doesn't
seem to be justified.
This commit is contained in:
joerg 2023-06-04 01:24:56 +00:00
parent 0bee435acd
commit 3caa8dc735
19 changed files with 112 additions and 116 deletions

View File

@ -43,9 +43,10 @@ This is normally def->st_value + rela->r_addend.
(c) R_TYPE(TLS_TPOFF): Static TLS offset. The code has to check whether
the static TLS offset for this module has been allocated
(defobj->tls_done) and otherwise call _rtld_tls_offset_allocate(). This
(defobj->tls_static) and otherwise call _rtld_tls_offset_allocate(). This
may fail if no static space is available and the object has been pulled
in via dlopen(3).
in via dlopen(3). It can also fail if the TLS area has already been used
via a global-dynamic allocation.
For TLS Variant I, this is typically:

View File

@ -1,4 +1,4 @@
/* $NetBSD: mdreloc.c,v 1.17 2022/12/03 09:10:40 skrll Exp $ */
/* $NetBSD: mdreloc.c,v 1.18 2023/06/04 01:24:56 joerg Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@ -60,7 +60,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.17 2022/12/03 09:10:40 skrll Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.18 2023/06/04 01:24:56 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@ -157,7 +157,7 @@ _rtld_tlsdesc_fill(const Obj_Entry *obj, const Elf_Rela *rela, Elf_Addr *where,
}
offs += rela->r_addend;
if (defobj->tls_done) {
if (defobj->tls_static) {
/* Variable is in initially allocated TLS segment */
where[0] = (Elf_Addr)_rtld_tlsdesc_static;
where[1] = defobj->tlsoffset + offs +
@ -299,8 +299,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
break;
case R_TLS_TYPE(TLS_TPREL):
if (!defobj->tls_done &&
_rtld_tls_offset_allocate(obj))
if (!defobj->tls_static &&
_rtld_tls_offset_allocate(__UNCONST(defobj)))
return -1;
*where = (Elf_Addr)(def->st_value + defobj->tlsoffset +

View File

@ -1,4 +1,4 @@
/* $NetBSD: alpha_reloc.c,v 1.43 2017/08/10 19:03:26 joerg Exp $ */
/* $NetBSD: alpha_reloc.c,v 1.44 2023/06/04 01:24:57 joerg Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -62,7 +62,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: alpha_reloc.c,v 1.43 2017/08/10 19:03:26 joerg Exp $");
__RCSID("$NetBSD: alpha_reloc.c,v 1.44 2023/06/04 01:24:57 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@ -280,8 +280,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
break;
case R_TYPE(TPREL64):
if (!defobj->tls_done &&
_rtld_tls_offset_allocate(obj))
if (!defobj->tls_static &&
_rtld_tls_offset_allocate(__UNCONST(defobj)))
return -1;
tmp = (Elf64_Addr)(def->st_value +

View File

@ -1,8 +1,8 @@
/* $NetBSD: mdreloc.c,v 1.45 2020/06/16 21:02:20 joerg Exp $ */
/* $NetBSD: mdreloc.c,v 1.46 2023/06/04 01:24:57 joerg Exp $ */
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.45 2020/06/16 21:02:20 joerg Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.46 2023/06/04 01:24:57 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@ -228,8 +228,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
break;
case R_TYPE(TLS_TPOFF32):
if (!defobj->tls_done &&
_rtld_tls_offset_allocate(obj))
if (!defobj->tls_static &&
_rtld_tls_offset_allocate(__UNCONST(defobj)))
return -1;
if (__predict_true(RELOC_ALIGNED_P(where)))

View File

@ -1,4 +1,4 @@
/* $NetBSD: hppa_reloc.c,v 1.49 2022/05/30 17:06:34 skrll Exp $ */
/* $NetBSD: hppa_reloc.c,v 1.50 2023/06/04 01:24:57 joerg Exp $ */
/*-
* Copyright (c) 2002, 2004 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hppa_reloc.c,v 1.49 2022/05/30 17:06:34 skrll Exp $");
__RCSID("$NetBSD: hppa_reloc.c,v 1.50 2023/06/04 01:24:57 joerg Exp $");
#endif /* not lint */
#include <stdlib.h>
@ -553,7 +553,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
break;
case R_TYPE(TLS_TPREL32):
if (!defobj->tls_done && _rtld_tls_offset_allocate(obj))
if (!defobj->tls_static &&
_rtld_tls_offset_allocate(__UNCONST(defobj)))
return -1;
*where = (Elf_Addr)(defobj->tlsoffset + def->st_value +

View File

@ -1,8 +1,8 @@
/* $NetBSD: mdreloc.c,v 1.41 2018/04/03 21:10:27 joerg Exp $ */
/* $NetBSD: mdreloc.c,v 1.42 2023/06/04 01:24:57 joerg Exp $ */
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.41 2018/04/03 21:10:27 joerg Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.42 2023/06/04 01:24:57 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@ -147,8 +147,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
break;
case R_TYPE(TLS_TPOFF):
if (!defobj->tls_done &&
_rtld_tls_offset_allocate(obj))
if (!defobj->tls_static &&
_rtld_tls_offset_allocate(__UNCONST(defobj)))
return -1;
*where += (Elf_Addr)(def->st_value - defobj->tlsoffset);
@ -159,8 +159,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
break;
case R_TYPE(TLS_TPOFF32):
if (!defobj->tls_done &&
_rtld_tls_offset_allocate(obj))
if (!defobj->tls_static &&
_rtld_tls_offset_allocate(__UNCONST(defobj)))
return -1;
*where += (Elf_Addr)(defobj->tlsoffset - def->st_value);

View File

@ -1,8 +1,8 @@
/* $NetBSD: mdreloc.c,v 1.33 2017/08/10 19:03:26 joerg Exp $ */
/* $NetBSD: mdreloc.c,v 1.34 2023/06/04 01:24:57 joerg Exp $ */
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.33 2017/08/10 19:03:26 joerg Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.34 2023/06/04 01:24:57 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@ -142,9 +142,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
break;
case R_TYPE(TLS_DTPREL32):
if (!defobj->tls_done && _rtld_tls_offset_allocate(obj))
return -1;
*where = (Elf_Addr)(def->st_value + rela->r_addend
- TLS_DTV_OFFSET);
rdbg(("DTPREL32 %s in %s --> %p in %s",
@ -153,7 +150,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
break;
case R_TYPE(TLS_TPREL32):
if (!defobj->tls_done && _rtld_tls_offset_allocate(obj))
if (!defobj->tls_static &&
_rtld_tls_offset_allocate(__UNCONST(defobj)))
return -1;
*where = (Elf_Addr)(def->st_value + rela->r_addend

View File

@ -1,4 +1,4 @@
/* $NetBSD: mips_reloc.c,v 1.74 2021/03/06 20:11:08 christos Exp $ */
/* $NetBSD: mips_reloc.c,v 1.75 2023/06/04 01:24:57 joerg Exp $ */
/*
* Copyright 1997 Michael L. Hitch <mhitch@montana.edu>
@ -30,7 +30,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mips_reloc.c,v 1.74 2021/03/06 20:11:08 christos Exp $");
__RCSID("$NetBSD: mips_reloc.c,v 1.75 2023/06/04 01:24:57 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@ -429,9 +429,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
Elf_Addr old = load_ptr(where, ELFSIZE / 8);
Elf_Addr val = old;
if (!defobj->tls_done && _rtld_tls_offset_allocate(obj))
return -1;
val += (Elf_Addr)def->st_value - TLS_DTV_OFFSET;
store_ptr(where, val, ELFSIZE / 8);
@ -450,7 +447,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
Elf_Addr old = load_ptr(where, ELFSIZE / 8);
Elf_Addr val = old;
if (!defobj->tls_done && _rtld_tls_offset_allocate(obj))
if (!defobj->tls_static &&
_rtld_tls_offset_allocate(__UNCONST(defobj)))
return -1;
val += (Elf_Addr)(def->st_value + defobj->tlsoffset

View File

@ -1,4 +1,4 @@
/* $NetBSD: mdreloc.c,v 1.3 2017/08/10 19:03:26 joerg Exp $ */
/* $NetBSD: mdreloc.c,v 1.4 2023/06/04 01:24:57 joerg Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.3 2017/08/10 19:03:26 joerg Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.4 2023/06/04 01:24:57 joerg Exp $");
#endif /* not lint */
#include <stdarg.h>
@ -171,9 +171,6 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
break;
case R_TYPE(TLS_DTPOFF):
if (!defobj->tls_done && _rtld_tls_offset_allocate(obj))
return -1;
*where = (Elf_Addr)(def->st_value + rela->r_addend
- TLS_DTV_OFFSET);
rdbg(("DTPOFF %s in %s --> %p in %s",
@ -182,7 +179,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
break;
case R_TYPE(TLS_TPOFF):
if (!defobj->tls_done && _rtld_tls_offset_allocate(obj))
if (!defobj->tls_static &&
_rtld_tls_offset_allocate(__UNCONST(defobj)))
return -1;
*where = (Elf_Addr)(def->st_value + rela->r_addend

View File

@ -1,4 +1,4 @@
/* $NetBSD: ppc_reloc.c,v 1.62 2022/07/06 17:35:20 martin Exp $ */
/* $NetBSD: ppc_reloc.c,v 1.63 2023/06/04 01:24:57 joerg Exp $ */
/*-
* Copyright (C) 1998 Tsubai Masanari
@ -30,7 +30,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: ppc_reloc.c,v 1.62 2022/07/06 17:35:20 martin Exp $");
__RCSID("$NetBSD: ppc_reloc.c,v 1.63 2023/06/04 01:24:57 joerg Exp $");
#endif /* not lint */
#include <stdarg.h>
@ -321,7 +321,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
break;
case R_TYPE(TPREL):
if (!defobj->tls_done && _rtld_tls_offset_allocate(obj))
if (!defobj->tls_static &&
_rtld_tls_offset_allocate(__UNCONST(defobj)))
return -1;
*where = (Elf_Addr)(def->st_value + rela->r_addend

View File

@ -1,4 +1,4 @@
/* $NetBSD: mdreloc.c,v 1.8 2023/05/07 12:41:48 skrll Exp $ */
/* $NetBSD: mdreloc.c,v 1.9 2023/06/04 01:24:58 joerg Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.8 2023/05/07 12:41:48 skrll Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.9 2023/06/04 01:24:58 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@ -203,8 +203,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
}
case R_TYPESZ(TLS_TPREL):
if (!defobj->tls_done &&
_rtld_tls_offset_allocate(obj))
if (!defobj->tls_static &&
_rtld_tls_offset_allocate(__UNCONST(defobj)))
return -1;
*where = (Elf_Addr)(def->st_value + defobj->tlsoffset +

View File

@ -1,8 +1,8 @@
/* $NetBSD: mdreloc.c,v 1.35 2017/08/10 19:03:26 joerg Exp $ */
/* $NetBSD: mdreloc.c,v 1.36 2023/06/04 01:24:58 joerg Exp $ */
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.35 2017/08/10 19:03:26 joerg Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.36 2023/06/04 01:24:58 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@ -173,8 +173,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
break;
case R_TYPE(TLS_TPOFF32):
if (!defobj->tls_done &&
_rtld_tls_offset_allocate(obj))
if (!defobj->tls_static &&
_rtld_tls_offset_allocate(__UNCONST(defobj)))
return -1;
*where = (Elf_Addr)def->st_value +

View File

@ -1,4 +1,4 @@
/* $NetBSD: mdreloc.c,v 1.56 2023/06/02 08:51:46 andvar Exp $ */
/* $NetBSD: mdreloc.c,v 1.57 2023/06/04 01:24:58 joerg Exp $ */
/*-
* Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.56 2023/06/02 08:51:46 andvar Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.57 2023/06/04 01:24:58 joerg Exp $");
#endif /* not lint */
#include <machine/elf_support.h>
@ -282,9 +282,9 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
break;
case R_TYPE(TLS_TPOFF32):
if (!defobj->tls_done &&
_rtld_tls_offset_allocate(obj))
return -1;
if (!defobj->tls_static &&
_rtld_tls_offset_allocate(__UNCONST(defobj)))
return -1;
*where = (Elf_Addr)(def->st_value -
defobj->tlsoffset + rela->r_addend);

View File

@ -1,4 +1,4 @@
/* $NetBSD: mdreloc.c,v 1.69 2018/04/03 21:10:27 joerg Exp $ */
/* $NetBSD: mdreloc.c,v 1.70 2023/06/04 01:24:58 joerg Exp $ */
/*-
* Copyright (c) 2000 Eduardo Horvath.
@ -32,7 +32,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.69 2018/04/03 21:10:27 joerg Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.70 2023/06/04 01:24:58 joerg Exp $");
#endif /* not lint */
#include <machine/elf_support.h>
@ -383,9 +383,9 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
break;
case R_TYPE(TLS_TPOFF64):
if (!defobj->tls_done &&
_rtld_tls_offset_allocate(obj))
return -1;
if (!defobj->tls_static &&
_rtld_tls_offset_allocate(__UNCONST(defobj)))
return -1;
*where = (Elf64_Addr)(def->st_value -
defobj->tlsoffset + rela->r_addend);

View File

@ -1,4 +1,4 @@
/* $NetBSD: mdreloc.c,v 1.47 2018/04/03 21:10:27 joerg Exp $ */
/* $NetBSD: mdreloc.c,v 1.48 2023/06/04 01:24:58 joerg Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -68,7 +68,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.47 2018/04/03 21:10:27 joerg Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.48 2023/06/04 01:24:58 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@ -226,8 +226,8 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
break;
case R_TYPE(TPOFF64):
if (!defobj->tls_done &&
_rtld_tls_offset_allocate(obj))
if (!defobj->tls_static &&
_rtld_tls_offset_allocate(__UNCONST(defobj)))
return -1;
*where64 = (Elf64_Addr)(def->st_value -

View File

@ -1,4 +1,4 @@
/* $NetBSD: map_object.c,v 1.66 2023/05/31 18:44:39 riastradh Exp $ */
/* $NetBSD: map_object.c,v 1.67 2023/06/04 01:24:56 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -34,7 +34,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: map_object.c,v 1.66 2023/05/31 18:44:39 riastradh Exp $");
__RCSID("$NetBSD: map_object.c,v 1.67 2023/06/04 01:24:56 joerg Exp $");
#endif /* not lint */
#include <errno.h>
@ -490,7 +490,7 @@ _rtld_obj_free(Obj_Entry *obj)
Name_Entry *entry;
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
if (obj->tls_done)
if (obj->tls_static)
_rtld_tls_offset_free(obj);
#endif
xfree(obj->path);

View File

@ -1,4 +1,4 @@
/* $NetBSD: rtld.h,v 1.145 2023/04/18 16:48:45 christos Exp $ */
/* $NetBSD: rtld.h,v 1.146 2023/06/04 01:24:56 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -219,7 +219,9 @@ typedef struct Struct_Obj_Entry {
phdr_loaded:1, /* Phdr is loaded and doesn't need to
* be freed. */
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
tls_done:1, /* True if static TLS offset
tls_static:1, /* True if static TLS offset
* has been allocated */
tls_dynamic:1, /* True if any non-static DTV entry
* has been allocated */
#endif
ref_nodel:1, /* Refcount increased to prevent dlclose */
@ -483,7 +485,6 @@ _rtld_fetch_ventry(const Obj_Entry *obj, unsigned long symnum)
/* tls.c */
void *_rtld_tls_get_addr(void *, size_t, size_t);
void _rtld_tls_initial_allocation(void);
void *_rtld_tls_module_allocate(size_t index);
int _rtld_tls_offset_allocate(Obj_Entry *);
void _rtld_tls_offset_free(Obj_Entry *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: tls.c,v 1.17 2023/06/01 08:20:10 riastradh Exp $ */
/* $NetBSD: tls.c,v 1.18 2023/06/04 01:24:56 joerg Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: tls.c,v 1.17 2023/06/01 08:20:10 riastradh Exp $");
__RCSID("$NetBSD: tls.c,v 1.18 2023/06/04 01:24:56 joerg Exp $");
#include <sys/param.h>
#include <sys/ucontext.h>
@ -43,6 +43,7 @@ __RCSID("$NetBSD: tls.c,v 1.17 2023/06/01 08:20:10 riastradh Exp $");
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
static struct tls_tcb *_rtld_tls_allocate_locked(void);
static void *_rtld_tls_module_allocate(struct tls_tcb *, size_t);
#ifndef TLS_DTV_OFFSET
#define TLS_DTV_OFFSET 0
@ -84,7 +85,7 @@ _rtld_tls_get_addr(void *tls, size_t idx, size_t offset)
}
if (__predict_false(dtv[idx] == NULL))
dtv[idx] = _rtld_tls_module_allocate(idx);
dtv[idx] = _rtld_tls_module_allocate(tcb, idx);
_rtld_exclusive_exit(&mask);
@ -136,7 +137,7 @@ _rtld_tls_allocate_locked(void)
SET_DTV_GENERATION(tcb->tcb_dtv, _rtld_tls_dtv_generation);
for (obj = _rtld_objlist; obj != NULL; obj = obj->next) {
if (obj->tls_done) {
if (obj->tls_static) {
#ifdef __HAVE_TLS_VARIANT_I
q = p + obj->tlsoffset;
#else
@ -195,8 +196,8 @@ _rtld_tls_free(struct tls_tcb *tcb)
_rtld_exclusive_exit(&mask);
}
void *
_rtld_tls_module_allocate(size_t idx)
static void *
_rtld_tls_module_allocate(struct tls_tcb *tcb, size_t idx)
{
Obj_Entry *obj;
uint8_t *p;
@ -209,11 +210,21 @@ _rtld_tls_module_allocate(size_t idx)
_rtld_error("Module for TLS index %zu missing", idx);
_rtld_die();
}
if (obj->tls_static) {
#ifdef __HAVE_TLS_VARIANT_I
p = (uint8_t *)tcb + obj->tlsoffset;
#else
p = (uint8_t *)tcb - obj->tlsoffset;
#endif
return p;
}
p = xmalloc(obj->tlssize);
memcpy(p, obj->tlsinit, obj->tlsinitsize);
memset(p + obj->tlsinitsize, 0, obj->tlssize - obj->tlsinitsize);
obj->tls_dynamic = 1;
return p;
}
@ -222,11 +233,14 @@ _rtld_tls_offset_allocate(Obj_Entry *obj)
{
size_t offset, next_offset;
if (obj->tls_done)
if (obj->tls_dynamic)
return -1;
if (obj->tls_static)
return 0;
if (obj->tlssize == 0) {
obj->tlsoffset = 0;
obj->tls_done = 1;
obj->tls_static = 1;
return 0;
}
@ -265,7 +279,7 @@ _rtld_tls_offset_allocate(Obj_Entry *obj)
dbg(("%s: static tls offset 0x%zx size %zu\n",
obj->path, obj->tlsoffset, obj->tlssize));
_rtld_tls_static_offset = next_offset;
obj->tls_done = 1;
obj->tls_static = 1;
return 0;
}
@ -277,7 +291,7 @@ _rtld_tls_offset_free(Obj_Entry *obj)
/*
* XXX See above.
*/
obj->tls_done = 0;
obj->tls_static = 0;
return;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: t_tls_extern.c,v 1.11 2023/06/02 19:09:11 riastradh Exp $ */
/* $NetBSD: t_tls_extern.c,v 1.12 2023/06/04 01:24:58 joerg Exp $ */
/*-
* Copyright (c) 2023 The NetBSD Foundation, Inc.
@ -41,8 +41,7 @@ enum order {
};
static void
tls_extern(const char *libdef, const char *libuse, enum order order,
bool xfail)
tls_extern(const char *libdef, const char *libuse, enum order order)
{
void *def, *use;
int *(*fdef)(void), *(*fuse)(void);
@ -77,10 +76,6 @@ lazy: ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
break;
}
if (xfail) {
atf_tc_expect_fail("PR toolchain/50277:"
" rtld relocation bug with thread local storage");
}
ATF_CHECK_EQ_MSG(pdef, puse,
"%p in defining library != %p in using library",
pdef, puse);
@ -94,8 +89,7 @@ ATF_TC_HEAD(dynamic_abusedef, tc)
}
ATF_TC_BODY(dynamic_abusedef, tc)
{
tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
USE_DEF, /*xfail*/true);
tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so", USE_DEF);
}
ATF_TC(dynamic_abusedefnoload);
@ -107,7 +101,7 @@ ATF_TC_HEAD(dynamic_abusedefnoload, tc)
ATF_TC_BODY(dynamic_abusedefnoload, tc)
{
tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
USE_DEF_NOLOAD, /*xfail*/true);
USE_DEF_NOLOAD);
}
ATF_TC(dynamic_defabuse_eager);
@ -124,7 +118,6 @@ ATF_TC_BODY(dynamic_defabuse_eager, tc)
ATF_REQUIRE_DL(def = dlopen("libh_def_dynamic.so", 0));
ATF_REQUIRE_DL(fdef = dlsym(def, "fdef"));
(void)(*fdef)();
atf_tc_expect_fail("rtld fails to detect dynamic-then-static abuse");
ATF_CHECK_EQ_MSG(NULL, dlopen("libh_abuse_dynamic.so", 0),
"dlopen failed to detect static-then-dynamic abuse");
}
@ -138,7 +131,7 @@ ATF_TC_HEAD(dynamic_defabuse_lazy, tc)
ATF_TC_BODY(dynamic_defabuse_lazy, tc)
{
tls_extern("libh_def_dynamic.so", "libh_abuse_dynamic.so",
DEF_USE_LAZY, /*xfail*/true);
DEF_USE_LAZY);
}
ATF_TC(dynamic_defuse_eager);
@ -150,7 +143,7 @@ ATF_TC_HEAD(dynamic_defuse_eager, tc)
ATF_TC_BODY(dynamic_defuse_eager, tc)
{
tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
DEF_USE_EAGER, /*xfail*/false);
DEF_USE_EAGER);
}
ATF_TC(dynamic_defuse_lazy);
@ -162,7 +155,7 @@ ATF_TC_HEAD(dynamic_defuse_lazy, tc)
ATF_TC_BODY(dynamic_defuse_lazy, tc)
{
tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
DEF_USE_LAZY, /*xfail*/false);
DEF_USE_LAZY);
}
ATF_TC(dynamic_usedef);
@ -174,7 +167,7 @@ ATF_TC_HEAD(dynamic_usedef, tc)
ATF_TC_BODY(dynamic_usedef, tc)
{
tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
USE_DEF, /*xfail*/false);
USE_DEF);
}
ATF_TC(dynamic_usedefnoload);
@ -186,7 +179,7 @@ ATF_TC_HEAD(dynamic_usedefnoload, tc)
ATF_TC_BODY(dynamic_usedefnoload, tc)
{
tls_extern("libh_def_dynamic.so", "libh_use_dynamic.so",
USE_DEF_NOLOAD, /*xfail*/false);
USE_DEF_NOLOAD);
}
ATF_TC(static_abusedef);
@ -197,8 +190,7 @@ ATF_TC_HEAD(static_abusedef, tc)
}
ATF_TC_BODY(static_abusedef, tc)
{
tls_extern("libh_def_static.so", "libh_abuse_static.so",
USE_DEF, /*xfail*/true);
tls_extern("libh_def_static.so", "libh_abuse_static.so", USE_DEF);
}
ATF_TC(static_abusedefnoload);
@ -210,7 +202,7 @@ ATF_TC_HEAD(static_abusedefnoload, tc)
ATF_TC_BODY(static_abusedefnoload, tc)
{
tls_extern("libh_def_static.so", "libh_abuse_static.so",
USE_DEF_NOLOAD, /*xfail*/true);
USE_DEF_NOLOAD);
}
ATF_TC(static_defabuse_eager);
@ -222,7 +214,7 @@ ATF_TC_HEAD(static_defabuse_eager, tc)
ATF_TC_BODY(static_defabuse_eager, tc)
{
tls_extern("libh_def_static.so", "libh_abuse_static.so",
DEF_USE_EAGER, /*xfail*/true);
DEF_USE_EAGER);
}
ATF_TC(static_defabuse_lazy);
@ -234,7 +226,7 @@ ATF_TC_HEAD(static_defabuse_lazy, tc)
ATF_TC_BODY(static_defabuse_lazy, tc)
{
tls_extern("libh_def_static.so", "libh_abuse_static.so",
DEF_USE_LAZY, /*xfail*/true);
DEF_USE_LAZY);
}
ATF_TC(static_defuse_eager);
@ -246,7 +238,7 @@ ATF_TC_HEAD(static_defuse_eager, tc)
ATF_TC_BODY(static_defuse_eager, tc)
{
tls_extern("libh_def_static.so", "libh_use_static.so",
DEF_USE_EAGER, /*xfail*/false);
DEF_USE_EAGER);
}
ATF_TC(static_defuse_lazy);
@ -258,7 +250,7 @@ ATF_TC_HEAD(static_defuse_lazy, tc)
ATF_TC_BODY(static_defuse_lazy, tc)
{
tls_extern("libh_def_static.so", "libh_use_static.so",
DEF_USE_LAZY, /*xfail*/false);
DEF_USE_LAZY);
}
ATF_TC(static_usedef);
@ -270,7 +262,7 @@ ATF_TC_HEAD(static_usedef, tc)
ATF_TC_BODY(static_usedef, tc)
{
tls_extern("libh_def_static.so", "libh_use_static.so",
USE_DEF, /*xfail*/true);
USE_DEF);
}
ATF_TC(static_usedefnoload);
@ -282,7 +274,7 @@ ATF_TC_HEAD(static_usedefnoload, tc)
ATF_TC_BODY(static_usedefnoload, tc)
{
tls_extern("libh_def_static.so", "libh_use_static.so",
USE_DEF_NOLOAD, /*xfail*/true);
USE_DEF_NOLOAD);
}
ATF_TC(onlydef_dynamic_static_ctor);
@ -296,7 +288,6 @@ ATF_TC_BODY(onlydef_dynamic_static_ctor, tc)
ATF_REQUIRE_DL(dlopen("libh_onlydef.so", 0));
ATF_REQUIRE_DL(dlopen("libh_onlyctor_dynamic.so", 0));
atf_tc_expect_fail("rtld fails to detect dynamic-then-static abuse");
ATF_CHECK_EQ_MSG(NULL, dlopen("libh_onlyuse_static.so", 0),
"dlopen failed to detect dynamic-then-static abuse");
}
@ -315,7 +306,6 @@ ATF_TC_BODY(onlydef_dynamic_static_eager, tc)
ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0));
ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic"));
(void)(*fdynamic)();
atf_tc_expect_fail("rtld fails to detect dynamic-then-static abuse");
ATF_CHECK_EQ_MSG(NULL, dlopen("libh_onlyuse_static.so", 0),
"dlopen failed to detect dynamic-then-static abuse");
}
@ -338,8 +328,6 @@ ATF_TC_BODY(onlydef_dynamic_static_lazy, tc)
ATF_REQUIRE_DL(fstatic = dlsym(use_static, "fstatic"));
pdynamic = (*fdynamic)();
pstatic = (*fstatic)();
atf_tc_expect_fail("PR toolchain/50277:"
" rtld relocation bug with thread local storage");
ATF_CHECK_EQ_MSG(pdynamic, pstatic,
"%p in dynamic tls user != %p in static tls user",
pdynamic, pstatic);
@ -365,8 +353,6 @@ ATF_TC_BODY(onlydef_static_dynamic_eager, tc)
ATF_REQUIRE_DL(use_dynamic = dlopen("libh_onlyuse_dynamic.so", 0));
ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic"));
pdynamic = (*fdynamic)();
atf_tc_expect_fail("PR toolchain/50277:"
" rtld relocation bug with thread local storage");
ATF_CHECK_EQ_MSG(pstatic, pdynamic,
"%p in static tls user != %p in dynamic tls user",
pstatic, pdynamic);
@ -391,8 +377,6 @@ ATF_TC_BODY(onlydef_static_dynamic_lazy, tc)
ATF_REQUIRE_DL(fdynamic = dlsym(use_dynamic, "fdynamic"));
pstatic = (*fstatic)();
pdynamic = (*fdynamic)();
atf_tc_expect_fail("PR toolchain/50277:"
" rtld relocation bug with thread local storage");
ATF_CHECK_EQ_MSG(pstatic, pdynamic,
"%p in static tls user != %p in dynamic tls user",
pstatic, pdynamic);