summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorKeegan Saunders <keegan@undefinedbehaviour.org>2022-11-27 15:46:17 -0500
committerAndreas Kling <kling@serenityos.org>2022-11-29 11:04:21 +0100
commite57533956428b4890421a5d5a7e4312e27859665 (patch)
treeed5dc66caaec6fb8cef8c572722ceb1390da92b5 /Userland
parent89b23c473a57ddc37c316cca9b21d7a636e86d81 (diff)
downloadserenity-e57533956428b4890421a5d5a7e4312e27859665.zip
LibELF: Add stack guard hardening
Employ the same hardening that glibc and the Linux kernel use for generating stack guards: zero the first byte of the guard such that if C-style string functions read out of bounds on the stack, we do not overwrite or potentially leak the stack guard.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibC/ssp.cpp1
-rw-r--r--Userland/Libraries/LibELF/DynamicLinker.cpp10
2 files changed, 10 insertions, 1 deletions
diff --git a/Userland/Libraries/LibC/ssp.cpp b/Userland/Libraries/LibC/ssp.cpp
index 8735f437d7..126a946b86 100644
--- a/Userland/Libraries/LibC/ssp.cpp
+++ b/Userland/Libraries/LibC/ssp.cpp
@@ -18,6 +18,7 @@
extern "C" {
extern uintptr_t __stack_chk_guard;
+// Initialized in `initialize_libc` (we leave a placeholder value here before initialization).
__attribute__((used)) uintptr_t __stack_chk_guard = (uintptr_t)0xc6c7c8c9;
__attribute__((noreturn)) void __stack_chk_fail()
diff --git a/Userland/Libraries/LibELF/DynamicLinker.cpp b/Userland/Libraries/LibELF/DynamicLinker.cpp
index ee4ee79eac..379bd57fec 100644
--- a/Userland/Libraries/LibELF/DynamicLinker.cpp
+++ b/Userland/Libraries/LibELF/DynamicLinker.cpp
@@ -13,6 +13,7 @@
#include <AK/HashTable.h>
#include <AK/LexicalPath.h>
#include <AK/NonnullRefPtrVector.h>
+#include <AK/Platform.h>
#include <AK/ScopeGuard.h>
#include <AK/Vector.h>
#include <LibC/bits/pthread_integration.h>
@@ -258,7 +259,14 @@ static void initialize_libc(DynamicObject& libc)
// This is not done in __libc_init, as we definitely have to return from that, and it might affect Loader as well.
res = libc.lookup_symbol("__stack_chk_guard"sv);
VERIFY(res.has_value());
- arc4random_buf(res.value().address.as_ptr(), sizeof(uintptr_t));
+ void* stack_guard = res.value().address.as_ptr();
+ arc4random_buf(stack_guard, sizeof(uintptr_t));
+
+#ifdef AK_ARCH_64_BIT
+ // For 64-bit platforms 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.
+ ((char*)stack_guard)[0] = 0;
+#endif
res = libc.lookup_symbol("__environ_is_malloced"sv);
VERIFY(res.has_value());