Procházet zdrojové kódy

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.
Dan Klishch před 1 rokem
rodič
revize
c9a6bcf81d

+ 13 - 4
Userland/DynamicLoader/main.cpp

@@ -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;

+ 17 - 13
Userland/Libraries/LibC/libcinit.cpp

@@ -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();
-    __malloc_init();
-    __stdio_init();
-}
 
-static void __auxiliary_vector_init()
-{
     char** env;
-    for (env = environ; *env; ++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();
 }
 }

+ 1 - 1
Userland/Libraries/LibC/sys/internals.h

@@ -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);

+ 1 - 6
Userland/Libraries/LibELF/DynamicLinker.cpp

@@ -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>