path: root/ldso
diff options
authorRich Felker <>2019-03-03 09:57:19 -0500
committerRich Felker <>2019-03-03 12:06:44 -0500
commit2f1f51ae7b2d78247568e7fdb8462f3c19e469a4 (patch)
tree8aba33ec7fe11fb172bf9e715edfc4841600b405 /ldso
parent8e43b5613eea0b557a2e91368917a90f4b0e4ab2 (diff)
fix malloc misuse for startup ctor queue, breakage on fdpic archs
in the case where malloc is being replaced, it's not valid to call malloc between final relocations and main app's crt1 entry point; on fdpic archs the main app's entry point will not yet have performed the self-fixups necessary to call its code. to fix, reorder queue_ctors before final relocations. an alternative solution would be doing the allocation from __libc_start_init, after the entry point but before any ctors run. this is less desirable, since it would leave a call to malloc that might be provided by the application happening at startup when doing so can be easily avoided.
Diffstat (limited to 'ldso')
1 files changed, 9 insertions, 5 deletions
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 20328285..a2f059cb 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -1479,9 +1479,7 @@ static void do_init_fini(struct dso **queue)
void __libc_start_init(void)
- /* This is valid because the queue was allocated after redoing
- * relocations with any interposed malloc having taken effect. */
- free(main_ctor_queue);
+ if (!__malloc_replaced) free(main_ctor_queue);
main_ctor_queue = 0;
@@ -1851,6 +1849,14 @@ _Noreturn void __dls3(size_t *sp)
+ /* This must be done before final relocations, since it calls
+ * malloc, which may be provided by the application. Calling any
+ * application code prior to the jump to its entry point is not
+ * valid in our model and does not work with FDPIC, where there
+ * are additional relocation-like fixups that only the entry point
+ * code can see to perform. */
+ main_ctor_queue = queue_ctors(&app);
/* The main program must be relocated LAST since it may contin
* copy relocations which depend on libraries' relocations. */
@@ -1879,8 +1885,6 @@ _Noreturn void __dls3(size_t *sp)
static_tls_cnt = tls_cnt;
- main_ctor_queue = queue_ctors(&app);
if (ldso_fail) _exit(127);
if (ldd_mode) _exit(0);