From 3c6fe6e741644185989ae79ee475cb799f12cc37 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 21 Aug 2019 10:51:51 +0200 Subject: [PATCH] ldso: statically allocate initial heap block This patch enables the fork.run script to run on base-linux. It should be regarded as an interim solution, however, because the randomization performed by the Linux kernel may still - by chance - produce a situation where one of the libc's malloc heap regions intersects with another dataspace dynamically attached to the child. The better solution would be to make the 'Region_map_mmap' implementation not depend on the kernel's allocation policy by using a locally implemented allocator. Issue #3478 --- repos/base/src/lib/ldso/main.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/repos/base/src/lib/ldso/main.cc b/repos/base/src/lib/ldso/main.cc index d1f2a2496c..69fac32a1b 100644 --- a/repos/base/src/lib/ldso/main.cc +++ b/repos/base/src/lib/ldso/main.cc @@ -649,7 +649,19 @@ static Genode::Constructible &heap() void Genode::init_ldso_phdr(Env &env) { - heap().construct(env.ram(), env.rm()); + /* + * Use a statically allocated initial block to make the first dynamic + * allocations deterministic. This assumption is required by the libc's + * fork mechanism on Linux. Without the initial block, the Linux kernel + * would attach the heap's backing-store dataspaces to differently + * randomized addresses in the new process. The binary's GOT (containing + * pointers to the linker's heap-allocated objects) of the new process, + * however, is copied from the parent process. So the pointed-to objects + * must reside on the same addresses in the parent and child. + */ + static char initial_block[4*1024]; + heap().construct(&env.ram(), &env.rm(), Heap::UNLIMITED, + initial_block, sizeof(initial_block)); /* load program headers of linker now */ if (!Ld::linker().file())