LibC+LibELF: Use AT_RANDOM ELF auxiliary vector for __stack_chk_guard

Kernel provided it for about 4 years at this point. I think it is about
time to finally use it in userspace.
This commit is contained in:
Dan Klishch 2024-04-20 19:33:27 -04:00 committed by Andrew Kaster
commit c9a6bcf81d
Notes: sideshowbarker 2024-07-16 20:51:53 +09:00
4 changed files with 33 additions and 25 deletions

View file

@ -16,9 +16,7 @@
char* __static_environ[] = { nullptr }; // We don't get the environment without some libc workarounds..
char** environ = __static_environ;
// FIXME: Kernel should give us a random value for __stack_chk_guard.
uintptr_t __stack_chk_guard = 0xe0e6'066b'b7ea'c300;
uintptr_t __stack_chk_guard = 0;
static void perform_self_relocations(auxv_t* auxvp)
{
@ -112,11 +110,22 @@ void _entry(int argc, char** argv, char** envp)
}
auxv_t* auxvp = (auxv_t*)++env;
bool at_random_found = false;
for (auxv_t* entry = auxvp; entry->a_type != AT_NULL; ++entry) {
if (entry->a_type == AT_RANDOM) {
at_random_found = true;
__stack_chk_guard = *reinterpret_cast<u64*>(entry->a_un.a_ptr);
break;
}
}
VERIFY(at_random_found);
perform_self_relocations(auxvp);
// Initialize the copy of libc included statically in Loader.so,
// initialization of the dynamic libc.so is done by the DynamicLinker
__libc_init(0);
__libc_init();
int main_program_fd = -1;
ByteString main_program_path;

View file

@ -7,6 +7,7 @@
#include <AK/Types.h>
#include <assert.h>
#include <errno.h>
#include <sys/auxv.h>
#include <sys/internals.h>
#include <unistd.h>
@ -28,30 +29,33 @@ char** environ = reinterpret_cast<char**>(explode_byte(0xe2));
uintptr_t __stack_chk_guard;
#endif
static void __auxiliary_vector_init();
int* __errno_location()
{
return &errno_storage;
}
void __libc_init([[maybe_unused]] uintptr_t cookie)
void __libc_init()
{
#ifndef _DYNAMIC_LOADER
__stack_chk_guard = cookie;
// We can only call magic functions until __stack_chk_guard is initialized.
environ = __environ_value();
#endif
__auxiliary_vector_init();
char** env;
for (env = environ; *env; ++env)
;
__auxiliary_vector = (void*)++env;
#ifndef _DYNAMIC_LOADER
for (auxv_t* entry = reinterpret_cast<auxv_t*>(__auxiliary_vector); entry->a_type != AT_NULL; ++entry)
if (entry->a_type == AT_RANDOM)
__stack_chk_guard = *(reinterpret_cast<u64*>(entry->a_un.a_ptr) + 1);
// We include an additional hardening: zero the first byte of the stack guard to avoid leaking
// or overwriting the stack guard with C-style string functions.
__stack_chk_guard &= ~0xffULL;
#endif
__malloc_init();
__stdio_init();
}
static void __auxiliary_vector_init()
{
char** env;
for (env = environ; *env; ++env) {
}
__auxiliary_vector = (void*)++env;
}
}

View file

@ -13,7 +13,7 @@ __BEGIN_DECLS
typedef void (*AtExitFunction)(void*);
extern void __libc_init(uintptr_t);
extern void __libc_init();
extern void __malloc_init(void);
extern void __stdio_init(void);
extern void __begin_atexit_locking(void);

View file

@ -315,15 +315,10 @@ static int __dl_iterate_phdr(DlIteratePhdrCallbackFunction callback, void* data)
static void initialize_libc(DynamicObject& libc)
{
uintptr_t stack_guard = get_random<uintptr_t>();
// We include an additional hardening: zero the first byte of the stack guard to avoid leaking
// or overwriting the stack guard with C-style string functions.
stack_guard &= ~0xffULL;
auto res = libc.lookup_symbol("__libc_init"sv);
VERIFY(res.has_value());
using libc_init_func = decltype(__libc_init);
((libc_init_func*)res.value().address.as_ptr())(stack_guard);
((libc_init_func*)res.value().address.as_ptr())();
}
template<typename Callback>