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:
parent
0bee435acd
commit
3caa8dc735
|
@ -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:
|
||||
|
||||
|
|
|
@ -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 +
|
||||
|
|
|
@ -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 +
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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 +
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 +
|
||||
|
|
|
@ -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 +
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 -
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue