From dff9e536587fa4128dd472fad2f1bd9e93943c1b Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Mon, 19 Feb 2024 15:00:42 -0800 Subject: [PATCH] [init] Randomize load address of dynamic ELF modules Update init to use the new xoroshiro RNG to create a random load address for dynamic executables. Also pass an address past the end of the loader in the loader_arg to use when loading dynamic dependencies. --- src/libraries/j6/include/j6/init.h | 2 ++ src/user/ld.so/main.cpp | 3 +-- src/user/srv.init/loader.cpp | 11 +++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/libraries/j6/include/j6/init.h b/src/libraries/j6/include/j6/init.h index b5dcef1..12803dd 100644 --- a/src/libraries/j6/include/j6/init.h +++ b/src/libraries/j6/include/j6/init.h @@ -42,6 +42,8 @@ struct j6_arg_loader uintptr_t image_base; uintptr_t *got; uintptr_t entrypoint; + uintptr_t start_addr; + uintptr_t other; }; struct j6_arg_driver diff --git a/src/user/ld.so/main.cpp b/src/user/ld.so/main.cpp index 3dda4ec..b1893e5 100644 --- a/src/user/ld.so/main.cpp +++ b/src/user/ld.so/main.cpp @@ -37,7 +37,6 @@ ldso_init(j6_arg_header *stack_args, uintptr_t *got) } if (!arg_loader) { - j6::syslog("ld.so: error: did not get j6_arg_loader"); exit(127); } @@ -71,7 +70,7 @@ ldso_init(j6_arg_header *stack_args, uintptr_t *got) reinterpret_cast(arg_loader->got[0] + arg_loader->image_base)); all_images.push_back(&target_image); - all_images.load(vfs, 0xb00'0000); + all_images.load(vfs, arg_loader->start_addr); return arg_loader->entrypoint + arg_loader->image_base; } diff --git a/src/user/srv.init/loader.cpp b/src/user/srv.init/loader.cpp index e0c06b6..5d353dc 100644 --- a/src/user/srv.init/loader.cpp +++ b/src/user/srv.init/loader.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "j6romfs.h" #include "loader.h" @@ -20,6 +21,8 @@ static constexpr size_t MiB = 0x10'0000ull; static constexpr size_t stack_size = 16 * MiB; static constexpr uintptr_t stack_top = 0x7f0'0000'0000; +static util::xoroshiro256pp rng {0x123456}; + inline uintptr_t align_up(uintptr_t a) { return ((a-1) & ~(MiB-1)) + MiB; } j6_handle_t @@ -180,7 +183,9 @@ load_program( elf::file program_elf {program_data}; bool dyn = program_elf.type() == elf::filetype::shared; - uintptr_t program_image_base = dyn ? 0xa00'0000 : 0; + uintptr_t program_image_base = 0; + if (dyn) + program_image_base = (rng.next() & 0xffe0 + 16) << 20; if (!program_elf.valid(dyn ? elf::filetype::shared : elf::filetype::executable)) { j6::syslog(" ** error loading program '%s': ELF is invalid", path); @@ -250,8 +255,10 @@ load_program( return false; } - load_program_into(proc, ldso_elf, ldso_image_base, ldso_path); + uintptr_t eop = load_program_into(proc, ldso_elf, ldso_image_base, ldso_path); + eop = (eop & ~0xfffffull) + 0x100000; loader_arg->loader_base = ldso_image_base; + loader_arg->start_addr = eop; entrypoint = ldso_elf.entrypoint() + ldso_image_base; delete [] reinterpret_cast(ldso_data.pointer); break;