DivestOS/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-16.patch
Tad 181519cf38 Add bionic hardening patchsets from GrapheneOS
11 b3a0c2c5db
11 5412c37195 #explicit zero
11 31456ac632 #brk
11 58ebc243ea #random
11 5323b39f7e #undefined
11 6a91d9dddb #merge
11 a042b5a0ba #vla formatting
11 9ec639de1b #pthread
11 49571a0a49 #read only
11 149cc5ccb8 #zero
11 2e613ccbe7 #fork mmap
11 e239c7dff8 #memprot pthread
11 0b03d92b7f #xor
11 de08419b82 #junk
11 897d4903e2 #guard
11 648cd68ca3 #ptrhread guard
11 0bc4dbcbd2 #stack rand
10 aa9cc05d07
10 a8cdbb6352 #explicit zero
10 b28302c668 #brk
10 9f8be7d07c #random
10 cb91a7ee3a #undefined
10 08279e2fdd #merge
10 6a18bd565d #vla formatting
10 2f392c2d08 #pthread
10 8bbce1bc50 #read only
10 725f61db82 #zero
10 4cd257135f #fork mmap
10 9220cf622b #memprot pthread
10 8ef71d1ffd #memprot exit
10 0eaef1abbd #xor
10 64f1cc2148 #junk
10 5c42a527cf #guard
10 5cc8c34e60 #pthread guard
10 7f61cc8a1c #stack rand
9  abdf523d26
9  e4b9b31e6f #explicit zero
9  a3a22a63d2 #brk
9  7444dbc3cf #random
9  dcd3b72ac9 #undefined
9  543e1df342 #merge
9  611e5691f7 #vla formatting
9  8de97ce864 #pthread
9  a475717042 #read only
9  7f0947cc0e #zero
9  e9751d3370 #fork mmap
9  83cd86d0d5 #memprot pthread
9  1ebb165455 #memprot exit
9  488ba483cf #xor
9  f9351d884b #junk
9  85e5bca0a5 #move

Signed-off-by: Tad <tad@spotco.us>
2022-03-15 16:56:46 -04:00

99 lines
4.7 KiB
Diff

From 0bc4dbcbd27c7f48713913101fb3c868c215c1a3 Mon Sep 17 00:00:00 2001
From: Renlord <me@renlord.com>
Date: Sun, 20 Oct 2019 08:17:11 +1100
Subject: [PATCH] add secondary stack randomization
Signed-off-by: anupritaisno1 <www.anuprita804@gmail.com>
---
libc/bionic/pthread_create.cpp | 32 +++++++++++++++++++++++++++-----
libc/include/sys/cdefs.h | 1 +
2 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 336e69b597..3008e3cd27 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -29,6 +29,7 @@
#include <pthread.h>
#include <errno.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/prctl.h>
@@ -199,12 +200,24 @@ int __init_thread(pthread_internal_t* thread) {
ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_size) {
const StaticTlsLayout& layout = __libc_shared_globals()->static_tls_layout;
+ // round up if the given stack size is not in multiples of PAGE_SIZE
+ stack_size = __BIONIC_ALIGN(stack_size, PAGE_SIZE);
size_t thread_page_size = __BIONIC_ALIGN(sizeof(pthread_internal_t), PAGE_SIZE);
- // Allocate in order: stack guard, stack, guard page, pthread_internal_t, static TLS, guard page.
+ // Place a randomly sized gap above the stack, up to 10% as large as the stack
+ // on 32-bit and 50% on 64-bit where virtual memory is plentiful.
+#if __LP64__
+ size_t max_gap_size = stack_size / 2;
+#else
+ size_t max_gap_size = stack_size / 10;
+#endif
+ // Make sure random stack top guard size are multiples of PAGE_SIZE.
+ size_t gap_size = __BIONIC_ALIGN(arc4random_uniform(max_gap_size), PAGE_SIZE);
+
+ // Allocate in order: stack guard, stack, (random) guard page(s), pthread_internal_t, static TLS, guard page.
size_t mmap_size;
if (__builtin_add_overflow(stack_size, stack_guard_size, &mmap_size)) return {};
- if (__builtin_add_overflow(mmap_size, PTHREAD_GUARD_SIZE, &mmap_size)) return {};
+ if (__builtin_add_overflow(mmap_size, gap_size, &mmap_size)) return {};
if (__builtin_add_overflow(mmap_size, thread_page_size, &mmap_size)) return {};
if (__builtin_add_overflow(mmap_size, layout.size(), &mmap_size)) return {};
if (__builtin_add_overflow(mmap_size, PTHREAD_GUARD_SIZE, &mmap_size)) return {};
@@ -226,15 +239,21 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si
return {};
}
- if (mprotect(space + stack_guard_size, stack_size, PROT_READ | PROT_WRITE) != 0) {
+ // Stack is at the lower end of mapped space, stack guard region is at the lower end of stack.
+ // Make the usable portion of the stack between the guard region and random gap readable and
+ // writable.
+ if (mprotect((space + stack_guard_size), stack_size, PROT_READ | PROT_WRITE) == -1) {
async_safe_format_log(ANDROID_LOG_WARN, "libc",
"pthread_create failed: couldn't mprotect R+W %zu-byte thread mapping region: %s",
stack_size, strerror(errno));
munmap(space, mmap_size);
return {};
}
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, space, stack_guard_size, "stack guard");
+ char* const stack_top_guard = space + stack_guard_size + stack_size;
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, stack_top_guard, gap_size, "stack top guard");
- char* const thread = space + stack_guard_size + stack_size + PTHREAD_GUARD_SIZE;
+ char* const thread = space + stack_guard_size + stack_size + gap_size;
char* const static_tls_space = thread + thread_page_size;
if (mprotect(thread, thread_page_size + layout.size(), PROT_READ | PROT_WRITE) != 0) {
@@ -252,7 +271,10 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si
result.mmap_size_unguarded = mmap_size - stack_guard_size - PTHREAD_GUARD_SIZE;
result.static_tls = static_tls_space;
result.stack_base = space;
- result.stack_top = space + stack_guard_size + stack_size;
+ // Choose a random base within the first page of the stack. Waste no more
+ // than the space originally wasted by pthread_internal_t for compatibility.
+ result.stack_top = space + stack_guard_size + stack_size - arc4random_uniform(sizeof(pthread_internal_t));
+ result.stack_top = reinterpret_cast<char*>(__BIONIC_ALIGN_DOWN(reinterpret_cast<size_t>(result.stack_top), 16));
return result;
}
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index b4556a74e5..5b0b4fb097 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -61,6 +61,7 @@
#endif
#define __BIONIC_ALIGN(__value, __alignment) (((__value) + (__alignment)-1) & ~((__alignment)-1))
+#define __BIONIC_ALIGN_DOWN(value, alignment) ((value) & ~((alignment) - 1))
/*
* The __CONCAT macro is used to concatenate parts of symbol names, e.g.