summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorItamar <itamar8910@gmail.com>2021-09-20 12:13:05 +0300
committerAndreas Kling <kling@serenityos.org>2021-09-20 18:32:09 +0200
commita3360bcee8ee2e652cfbd5de157dee1f0e7e3bb7 (patch)
tree2d8cd504a82964bf22446087dfdab7716203e015
parent01900801e3c704740c215b4a2bb4f8aed638d486 (diff)
downloadserenity-a3360bcee8ee2e652cfbd5de157dee1f0e7e3bb7.zip
LibC+DynamicLoader: Store the auxiliary vector address at startup
Previously, getauxval() got the address of the auxiliary vector by traversing to the end of the `environ` pointer. The assumption that the auxiliary vector comes after the environment array is true at program startup, however the environment array may be re-allocated and change its address during runtime which would cause getauxval() to work with an incorrect auxiliary vector address. To fix this, we now get the address of the auxiliary vector once in __libc_init and store it in a libc-internal pointer which is then used by getauxval(). Fixes #10087.
-rw-r--r--Userland/Libraries/LibC/libcinit.cpp13
-rw-r--r--Userland/Libraries/LibC/stdlib.cpp5
-rw-r--r--Userland/Libraries/LibC/sys/internals.h1
3 files changed, 15 insertions, 4 deletions
diff --git a/Userland/Libraries/LibC/libcinit.cpp b/Userland/Libraries/LibC/libcinit.cpp
index 5fd80356af..09d81cbac4 100644
--- a/Userland/Libraries/LibC/libcinit.cpp
+++ b/Userland/Libraries/LibC/libcinit.cpp
@@ -19,10 +19,23 @@ __thread int errno;
char** environ;
bool __environ_is_malloced;
bool __stdio_is_initialized;
+void* __auxiliary_vector;
+
+static void __auxiliary_vector_init();
void __libc_init()
{
+ __auxiliary_vector_init();
__malloc_init();
__stdio_init();
}
+
+static void __auxiliary_vector_init()
+{
+ char** env;
+ for (env = environ; *env; ++env) {
+ }
+
+ __auxiliary_vector = (void*)++env;
+}
}
diff --git a/Userland/Libraries/LibC/stdlib.cpp b/Userland/Libraries/LibC/stdlib.cpp
index b40b8875a6..2bf5497f35 100644
--- a/Userland/Libraries/LibC/stdlib.cpp
+++ b/Userland/Libraries/LibC/stdlib.cpp
@@ -182,11 +182,8 @@ extern "C" {
long getauxval(long type)
{
errno = 0;
- char** env;
- for (env = environ; *env; ++env) {
- }
- auxv_t* auxvp = (auxv_t*)++env;
+ auxv_t* auxvp = (auxv_t*)__auxiliary_vector;
for (; auxvp->a_type != AT_NULL; ++auxvp) {
if (auxvp->a_type == type)
return auxvp->a_un.a_val;
diff --git a/Userland/Libraries/LibC/sys/internals.h b/Userland/Libraries/LibC/sys/internals.h
index 9f637eaf3f..b18115a377 100644
--- a/Userland/Libraries/LibC/sys/internals.h
+++ b/Userland/Libraries/LibC/sys/internals.h
@@ -19,6 +19,7 @@ extern void _init();
extern bool __environ_is_malloced;
extern bool __stdio_is_initialized;
extern bool __heap_is_stable;
+extern void* __auxiliary_vector;
int __cxa_atexit(AtExitFunction exit_function, void* parameter, void* dso_handle);
void __cxa_finalize(void* dso_handle);