aboutsummaryrefslogtreecommitdiff
path: root/elf/rtld.c
diff options
context:
space:
mode:
authorSzabolcs Nagy <szabolcs.nagy@arm.com>2020-07-07 10:49:11 +0100
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2020-07-08 17:32:56 +0100
commit17796419b5fd694348cceb65c3f77601faae082c (patch)
tree077996aa8d9b0151191a812928de0b8d10225c2d /elf/rtld.c
parent0c7b002fac12dcb2f53ba83ee56bb3b5d2439447 (diff)
downloadglibc-17796419b5fd694348cceb65c3f77601faae082c.zip
glibc-17796419b5fd694348cceb65c3f77601faae082c.tar.gz
glibc-17796419b5fd694348cceb65c3f77601faae082c.tar.bz2
rtld: Account static TLS surplus for audit modules
The new static TLS surplus size computation is surplus_tls = 192 * (nns-1) + 144 * nns + 512 where nns is controlled via the rtld.nns tunable. This commit accounts audit modules too so nns = rtld.nns + audit modules. rtld.nns should only include the namespaces required by the application, namespaces for audit modules are accounted on top of that so audit modules don't use up the static TLS that is reserved for the application. This allows loading many audit modules without tuning rtld.nns or using up static TLS, and it fixes FAIL: elf/tst-auditmany Note that DL_NNS is currently a hard upper limit for nns, and if rtld.nns + audit modules go over the limit that's a fatal error. By default rtld.nns is 4 which allows 12 audit modules. Counting the audit modules is based on existing audit string parsing code, we cannot use GLRO(dl_naudit) before the modules are actually loaded.
Diffstat (limited to 'elf/rtld.c')
-rw-r--r--elf/rtld.c31
1 files changed, 27 insertions, 4 deletions
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