aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
Diffstat (limited to 'elf')
-rw-r--r--elf/dl-tls.c15
-rw-r--r--elf/rtld.c31
2 files changed, 40 insertions, 6 deletions
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index 924ee5d..4e7b10e 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -49,7 +49,10 @@
that affects the size of the static TLS and by default it's small enough
not to cause problems with existing applications. The limit is not
enforced or checked: it is the user's responsibility to increase rtld.nns
- if more dlmopen namespaces are used. */
+ if more dlmopen namespaces are used.
+
+ Audit modules use their own namespaces, they are not included in rtld.nns,
+ but come on top when computing the number of namespaces. */
/* Size of initial-exec TLS in libc.so. */
#define LIBC_IE_TLS 192
@@ -60,8 +63,11 @@
/* Size of additional surplus TLS, placeholder for TLS optimizations. */
#define OPT_SURPLUS_TLS 512
+/* Calculate the size of the static TLS surplus, when the given
+ number of audit modules are loaded. Must be called after the
+ number of audit modules is known and before static TLS allocation. */
void
-_dl_tls_static_surplus_init (void)
+_dl_tls_static_surplus_init (size_t naudit)
{
size_t nns;
@@ -73,6 +79,11 @@ _dl_tls_static_surplus_init (void)
#endif
if (nns > DL_NNS)
nns = DL_NNS;
+ if (DL_NNS - nns < naudit)
+ _dl_fatal_printf ("Failed loading %lu audit modules, %lu are supported.\n",
+ (unsigned long) naudit, (unsigned long) (DL_NNS - nns));
+ nns += naudit;
+
GLRO(dl_tls_static_surplus) = ((nns - 1) * LIBC_IE_TLS
+ nns * OTHER_IE_TLS
+ OPT_SURPLUS_TLS);
diff --git a/elf/rtld.c b/elf/rtld.c
index f339f68..5b88216 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -299,6 +299,23 @@ audit_list_next (struct audit_list *list)
}
}
+/* Count audit modules before they are loaded so GLRO(dl_naudit)
+ is not yet usable. */
+static size_t
+audit_list_count (struct audit_list *list)
+{
+ /* Restore the audit_list iterator state at the end. */
+ const char *saved_tail = list->current_tail;
+ size_t naudit = 0;
+
+ assert (list->current_index == 0);
+ while (audit_list_next (list) != NULL)
+ naudit++;
+ list->current_tail = saved_tail;
+ list->current_index = 0;
+ return naudit;
+}
+
#ifndef HAVE_INLINED_SYSCALLS
/* Set nonzero during loading and initialization of executable and
libraries, cleared before the executable's entry point runs. This
@@ -738,7 +755,7 @@ match_version (const char *string, struct link_map *map)
static bool tls_init_tp_called;
static void *
-init_tls (void)
+init_tls (size_t naudit)
{
/* Number of elements in the static TLS block. */
GL(dl_tls_static_nelem) = GL(dl_tls_max_dtv_idx);
@@ -781,7 +798,7 @@ init_tls (void)
assert (i == GL(dl_tls_max_dtv_idx));
/* Calculate the size of the static TLS surplus. */
- _dl_tls_static_surplus_init ();
+ _dl_tls_static_surplus_init (naudit);
/* Compute the TLS offsets for the various blocks. */
_dl_determine_tlsoffset ();
@@ -1674,9 +1691,11 @@ of this helper program; chances are you did not intend to run this program.\n\
bool need_security_init = true;
if (audit_list.length > 0)
{
+ size_t naudit = audit_list_count (&audit_list);
+
/* Since we start using the auditing DSOs right away we need to
initialize the data structures now. */
- tcbp = init_tls ();
+ tcbp = init_tls (naudit);
/* Initialize security features. We need to do it this early
since otherwise the constructors of the audit libraries will
@@ -1686,6 +1705,10 @@ of this helper program; chances are you did not intend to run this program.\n\
need_security_init = false;
load_audit_modules (main_map, &audit_list);
+
+ /* The count based on audit strings may overestimate the number
+ of audit modules that got loaded, but not underestimate. */
+ assert (GLRO(dl_naudit) <= naudit);
}
/* Keep track of the currently loaded modules to count how many
@@ -1929,7 +1952,7 @@ of this helper program; chances are you did not intend to run this program.\n\
multiple threads (from a non-TLS-using libpthread). */
bool was_tls_init_tp_called = tls_init_tp_called;
if (tcbp == NULL)
- tcbp = init_tls ();
+ tcbp = init_tls (0);
if (__glibc_likely (need_security_init))
/* Initialize security features. But only if we have not done it