mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2025-09-28 14:39:33 -04:00
Add bionic hardening patchsets from GrapheneOS
11b3a0c2c5db
115412c37195
#explicit zero 1131456ac632
#brk 1158ebc243ea
#random 115323b39f7e
#undefined 116a91d9dddb
#merge 11a042b5a0ba
#vla formatting 119ec639de1b
#pthread 1149571a0a49
#read only 11149cc5ccb8
#zero 112e613ccbe7
#fork mmap 11e239c7dff8
#memprot pthread 110b03d92b7f
#xor 11de08419b82
#junk 11897d4903e2
#guard 11648cd68ca3
#ptrhread guard 110bc4dbcbd2
#stack rand 10aa9cc05d07
10a8cdbb6352
#explicit zero 10b28302c668
#brk 109f8be7d07c
#random 10cb91a7ee3a
#undefined 1008279e2fdd
#merge 106a18bd565d
#vla formatting 102f392c2d08
#pthread 108bbce1bc50
#read only 10725f61db82
#zero 104cd257135f
#fork mmap 109220cf622b
#memprot pthread 108ef71d1ffd
#memprot exit 100eaef1abbd
#xor 1064f1cc2148
#junk 105c42a527cf
#guard 105cc8c34e60
#pthread guard 107f61cc8a1c
#stack rand 9abdf523d26
9e4b9b31e6f
#explicit zero 9a3a22a63d2
#brk 97444dbc3cf
#random 9dcd3b72ac9
#undefined 9543e1df342
#merge 9611e5691f7
#vla formatting 98de97ce864
#pthread 9a475717042
#read only 97f0947cc0e
#zero 9e9751d3370
#fork mmap 983cd86d0d5
#memprot pthread 91ebb165455
#memprot exit 9488ba483cf
#xor 9f9351d884b
#junk 985e5bca0a5
#move Signed-off-by: Tad <tad@spotco.us>
This commit is contained in:
parent
1878cd19ab
commit
181519cf38
55 changed files with 3121 additions and 2 deletions
|
@ -0,0 +1,163 @@
|
|||
From e4b9b31e6f9ff7eb9d168db6a99a775bf4f669c1 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Thu, 5 Feb 2015 21:53:16 -0500
|
||||
Subject: [PATCH] add a real explicit_bzero implementation
|
||||
|
||||
Clang, GCC and other compilers special-case standard C functions like
|
||||
memset. Calls to memset will be optimized out.
|
||||
|
||||
OpenBSD provides explicit_bzero to work around this but Android simply
|
||||
defines it as memset so nothing prevents it from being optimized away.
|
||||
|
||||
This implementation uses a memory read constraint via empty inline
|
||||
assembly rather than something that may be broken via link-time
|
||||
optimization in the future.
|
||||
---
|
||||
libc/Android.bp | 1 +
|
||||
libc/bionic/explicit_bzero.cpp | 7 +++++++
|
||||
libc/include/string.h | 1 +
|
||||
libc/libc.arm.map | 1 +
|
||||
libc/libc.arm64.map | 1 +
|
||||
libc/libc.map.txt | 1 +
|
||||
libc/libc.mips.map | 1 +
|
||||
libc/libc.mips64.map | 1 +
|
||||
libc/libc.x86.map | 1 +
|
||||
libc/libc.x86_64.map | 1 +
|
||||
libc/upstream-openbsd/android/include/openbsd-compat.h | 2 --
|
||||
11 files changed, 16 insertions(+), 2 deletions(-)
|
||||
create mode 100644 libc/bionic/explicit_bzero.cpp
|
||||
|
||||
diff --git a/libc/Android.bp b/libc/Android.bp
|
||||
index 26ffc73b66..85a739e4e9 100644
|
||||
--- a/libc/Android.bp
|
||||
+++ b/libc/Android.bp
|
||||
@@ -1329,6 +1329,7 @@ cc_library_static {
|
||||
"bionic/eventfd_read.cpp",
|
||||
"bionic/eventfd_write.cpp",
|
||||
"bionic/exec.cpp",
|
||||
+ "bionic/explicit_bzero.cpp",
|
||||
"bionic/faccessat.cpp",
|
||||
"bionic/fchmod.cpp",
|
||||
"bionic/fchmodat.cpp",
|
||||
diff --git a/libc/bionic/explicit_bzero.cpp b/libc/bionic/explicit_bzero.cpp
|
||||
new file mode 100644
|
||||
index 0000000000..b06daa1386
|
||||
--- /dev/null
|
||||
+++ b/libc/bionic/explicit_bzero.cpp
|
||||
@@ -0,0 +1,7 @@
|
||||
+#include <string.h>
|
||||
+
|
||||
+void* explicit_bzero(void* s, size_t n) {
|
||||
+ void *ptr = memset(s, 0, n);
|
||||
+ __asm__ __volatile__("" : : "r"(ptr) : "memory");
|
||||
+ return ptr;
|
||||
+}
|
||||
diff --git a/libc/include/string.h b/libc/include/string.h
|
||||
index 54d5e1c800..5336777773 100644
|
||||
--- a/libc/include/string.h
|
||||
+++ b/libc/include/string.h
|
||||
@@ -56,6 +56,7 @@ void* mempcpy(void* __dst, const void* __src, size_t __n) __INTRODUCED_IN(23);
|
||||
#endif
|
||||
void* memmove(void* __dst, const void* __src, size_t __n);
|
||||
void* memset(void* __dst, int __ch, size_t __n);
|
||||
+void* explicit_bzero(void *s, size_t n);
|
||||
void* memmem(const void* __haystack, size_t __haystack_size, const void* __needle, size_t __needle_size) __attribute_pure__;
|
||||
|
||||
char* strchr(const char* __s, int __ch) __attribute_pure__;
|
||||
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
|
||||
index b0f96a9ffc..28ad4913f6 100644
|
||||
--- a/libc/libc.arm.map
|
||||
+++ b/libc/libc.arm.map
|
||||
@@ -330,6 +330,7 @@ LIBC {
|
||||
execvp;
|
||||
execvpe; # introduced=21
|
||||
exit;
|
||||
+ explicit_bzero;
|
||||
faccessat; # introduced-arm=16 introduced-arm64=21 introduced-mips=16 introduced-mips64=21 introduced-x86=16 introduced-x86_64=21
|
||||
fallocate; # introduced=21
|
||||
fallocate64; # introduced=21
|
||||
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
|
||||
index 6b0e415494..ee20108901 100644
|
||||
--- a/libc/libc.arm64.map
|
||||
+++ b/libc/libc.arm64.map
|
||||
@@ -260,6 +260,7 @@ LIBC {
|
||||
execvp;
|
||||
execvpe; # introduced=21
|
||||
exit;
|
||||
+ explicit_bzero;
|
||||
faccessat; # introduced-arm=16 introduced-arm64=21 introduced-mips=16 introduced-mips64=21 introduced-x86=16 introduced-x86_64=21
|
||||
fallocate; # introduced=21
|
||||
fallocate64; # introduced=21
|
||||
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
|
||||
index 85c9a581cb..6c7e3eb368 100644
|
||||
--- a/libc/libc.map.txt
|
||||
+++ b/libc/libc.map.txt
|
||||
@@ -332,6 +332,7 @@ LIBC {
|
||||
execvp;
|
||||
execvpe; # introduced=21
|
||||
exit;
|
||||
+ explicit_bzero;
|
||||
faccessat; # introduced-arm=16 introduced-arm64=21 introduced-mips=16 introduced-mips64=21 introduced-x86=16 introduced-x86_64=21
|
||||
fallocate; # introduced=21
|
||||
fallocate64; # introduced=21
|
||||
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
|
||||
index 9e760c2422..12faa5d86b 100644
|
||||
--- a/libc/libc.mips.map
|
||||
+++ b/libc/libc.mips.map
|
||||
@@ -328,6 +328,7 @@ LIBC {
|
||||
execvp;
|
||||
execvpe; # introduced=21
|
||||
exit;
|
||||
+ explicit_bzero;
|
||||
faccessat; # introduced-arm=16 introduced-arm64=21 introduced-mips=16 introduced-mips64=21 introduced-x86=16 introduced-x86_64=21
|
||||
fallocate; # introduced=21
|
||||
fallocate64; # introduced=21
|
||||
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
|
||||
index 6b0e415494..ee20108901 100644
|
||||
--- a/libc/libc.mips64.map
|
||||
+++ b/libc/libc.mips64.map
|
||||
@@ -260,6 +260,7 @@ LIBC {
|
||||
execvp;
|
||||
execvpe; # introduced=21
|
||||
exit;
|
||||
+ explicit_bzero;
|
||||
faccessat; # introduced-arm=16 introduced-arm64=21 introduced-mips=16 introduced-mips64=21 introduced-x86=16 introduced-x86_64=21
|
||||
fallocate; # introduced=21
|
||||
fallocate64; # introduced=21
|
||||
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
|
||||
index 2855f9e22d..8be30d8424 100644
|
||||
--- a/libc/libc.x86.map
|
||||
+++ b/libc/libc.x86.map
|
||||
@@ -326,6 +326,7 @@ LIBC {
|
||||
execvp;
|
||||
execvpe; # introduced=21
|
||||
exit;
|
||||
+ explicit_bzero;
|
||||
faccessat; # introduced-arm=16 introduced-arm64=21 introduced-mips=16 introduced-mips64=21 introduced-x86=16 introduced-x86_64=21
|
||||
fallocate; # introduced=21
|
||||
fallocate64; # introduced=21
|
||||
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
|
||||
index 6b0e415494..ee20108901 100644
|
||||
--- a/libc/libc.x86_64.map
|
||||
+++ b/libc/libc.x86_64.map
|
||||
@@ -260,6 +260,7 @@ LIBC {
|
||||
execvp;
|
||||
execvpe; # introduced=21
|
||||
exit;
|
||||
+ explicit_bzero;
|
||||
faccessat; # introduced-arm=16 introduced-arm64=21 introduced-mips=16 introduced-mips64=21 introduced-x86=16 introduced-x86_64=21
|
||||
fallocate; # introduced=21
|
||||
fallocate64; # introduced=21
|
||||
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
|
||||
index f178149311..929e61eeda 100644
|
||||
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
|
||||
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
|
||||
@@ -65,8 +65,6 @@ extern const char* __progname;
|
||||
/* OpenBSD has this, but we can't really implement it correctly on Linux. */
|
||||
#define issetugid() 0
|
||||
|
||||
-#define explicit_bzero(p, s) memset(p, 0, s)
|
||||
-
|
||||
/* OpenBSD has these in <sys/param.h>, but "ALIGN" isn't something we want to reserve. */
|
||||
#define ALIGNBYTES (sizeof(uintptr_t) - 1)
|
||||
#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)
|
|
@ -0,0 +1,85 @@
|
|||
From e9751d3370aa44e6ca77843f7c7a7aac67e5bcc0 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Wed, 2 Dec 2015 23:37:28 -0500
|
||||
Subject: [PATCH] switch pthread_atfork handler allocation to mmap
|
||||
|
||||
---
|
||||
libc/bionic/pthread_atfork.cpp | 35 ++++++++++++++++++++++++++++------
|
||||
1 file changed, 29 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/libc/bionic/pthread_atfork.cpp b/libc/bionic/pthread_atfork.cpp
|
||||
index 84e511c2e8..651c026df5 100644
|
||||
--- a/libc/bionic/pthread_atfork.cpp
|
||||
+++ b/libc/bionic/pthread_atfork.cpp
|
||||
@@ -29,8 +29,11 @@
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
+#include <sys/mman.h>
|
||||
+#include <unistd.h>
|
||||
|
||||
#include "private/bionic_macros.h"
|
||||
+#include "private/bionic_prctl.h"
|
||||
|
||||
struct atfork_t {
|
||||
atfork_t* next;
|
||||
@@ -43,6 +46,8 @@ struct atfork_t {
|
||||
void* dso_handle;
|
||||
};
|
||||
|
||||
+static atfork_t* pool;
|
||||
+
|
||||
class atfork_list_t {
|
||||
public:
|
||||
constexpr atfork_list_t() : first_(nullptr), last_(nullptr) {}
|
||||
@@ -101,7 +106,8 @@ class atfork_list_t {
|
||||
last_ = entry->prev;
|
||||
}
|
||||
|
||||
- free(entry);
|
||||
+ entry->next = pool;
|
||||
+ pool = entry;
|
||||
}
|
||||
|
||||
atfork_t* first_;
|
||||
@@ -154,18 +160,35 @@ void __bionic_atfork_run_parent() {
|
||||
// __register_atfork is the name used by glibc
|
||||
extern "C" int __register_atfork(void (*prepare)(void), void (*parent)(void),
|
||||
void(*child)(void), void* dso) {
|
||||
- atfork_t* entry = reinterpret_cast<atfork_t*>(malloc(sizeof(atfork_t)));
|
||||
- if (entry == nullptr) {
|
||||
- return ENOMEM;
|
||||
+ pthread_mutex_lock(&g_atfork_list_mutex);
|
||||
+
|
||||
+ if (!pool) {
|
||||
+ size_t page_size = getpagesize();
|
||||
+ char* page = static_cast<char*>(mmap(NULL, page_size, PROT_READ|PROT_WRITE,
|
||||
+ MAP_ANONYMOUS|MAP_PRIVATE, -1, 0));
|
||||
+ if (page == MAP_FAILED) {
|
||||
+ pthread_mutex_unlock(&g_atfork_list_mutex);
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, page, page_size,
|
||||
+ "atfork handlers");
|
||||
+
|
||||
+ for (char* it = page; it < page + page_size - sizeof(atfork_t); it += sizeof(atfork_t)) {
|
||||
+ atfork_t* node = reinterpret_cast<atfork_t*>(it);
|
||||
+ node->next = pool;
|
||||
+ pool = node;
|
||||
+ }
|
||||
}
|
||||
|
||||
+ atfork_t* entry = pool;
|
||||
+ pool = entry->next;
|
||||
+
|
||||
entry->prepare = prepare;
|
||||
entry->parent = parent;
|
||||
entry->child = child;
|
||||
entry->dso_handle = dso;
|
||||
|
||||
- pthread_mutex_lock(&g_atfork_list_mutex);
|
||||
-
|
||||
g_atfork_list.push_back(entry);
|
||||
|
||||
pthread_mutex_unlock(&g_atfork_list_mutex);
|
|
@ -0,0 +1,95 @@
|
|||
From 83cd86d0d522c64726dac41614c00f2534044f73 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Thu, 3 Dec 2015 12:58:31 -0500
|
||||
Subject: [PATCH] add memory protection for pthread_atfork handlers
|
||||
|
||||
---
|
||||
libc/bionic/pthread_atfork.cpp | 34 ++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 32 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libc/bionic/pthread_atfork.cpp b/libc/bionic/pthread_atfork.cpp
|
||||
index 651c026df5..91c5233f73 100644
|
||||
--- a/libc/bionic/pthread_atfork.cpp
|
||||
+++ b/libc/bionic/pthread_atfork.cpp
|
||||
@@ -47,6 +47,7 @@ struct atfork_t {
|
||||
};
|
||||
|
||||
static atfork_t* pool;
|
||||
+static atfork_t* page_list;
|
||||
|
||||
class atfork_list_t {
|
||||
public:
|
||||
@@ -160,13 +161,22 @@ void __bionic_atfork_run_parent() {
|
||||
// __register_atfork is the name used by glibc
|
||||
extern "C" int __register_atfork(void (*prepare)(void), void (*parent)(void),
|
||||
void(*child)(void), void* dso) {
|
||||
+ size_t page_size = getpagesize();
|
||||
+
|
||||
pthread_mutex_lock(&g_atfork_list_mutex);
|
||||
|
||||
+ for (atfork_t* page_it = page_list; page_it; page_it = page_it->next) {
|
||||
+ mprotect(page_it, page_size, PROT_READ|PROT_WRITE);
|
||||
+ }
|
||||
+
|
||||
if (!pool) {
|
||||
- size_t page_size = getpagesize();
|
||||
char* page = static_cast<char*>(mmap(NULL, page_size, PROT_READ|PROT_WRITE,
|
||||
MAP_ANONYMOUS|MAP_PRIVATE, -1, 0));
|
||||
if (page == MAP_FAILED) {
|
||||
+ for (atfork_t* page_it = page_list; page_it; page_it = page_it->next) {
|
||||
+ mprotect(page_it, page_size, PROT_READ);
|
||||
+ }
|
||||
+
|
||||
pthread_mutex_unlock(&g_atfork_list_mutex);
|
||||
return ENOMEM;
|
||||
}
|
||||
@@ -174,11 +184,15 @@ extern "C" int __register_atfork(void (*prepare)(void), void (*parent)(void),
|
||||
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, page, page_size,
|
||||
"atfork handlers");
|
||||
|
||||
- for (char* it = page; it < page + page_size - sizeof(atfork_t); it += sizeof(atfork_t)) {
|
||||
+ for (char* it = page + sizeof(atfork_t); it < page + page_size - sizeof(atfork_t); it += sizeof(atfork_t)) {
|
||||
atfork_t* node = reinterpret_cast<atfork_t*>(it);
|
||||
node->next = pool;
|
||||
pool = node;
|
||||
}
|
||||
+
|
||||
+ atfork_t* page_node = reinterpret_cast<atfork_t*>(page);
|
||||
+ page_node->next = page_list;
|
||||
+ page_list = page_node;
|
||||
}
|
||||
|
||||
atfork_t* entry = pool;
|
||||
@@ -191,6 +205,10 @@ extern "C" int __register_atfork(void (*prepare)(void), void (*parent)(void),
|
||||
|
||||
g_atfork_list.push_back(entry);
|
||||
|
||||
+ for (atfork_t* page_it = page_list; page_it; page_it = page_it->next) {
|
||||
+ mprotect(page_it, page_size, PROT_READ);
|
||||
+ }
|
||||
+
|
||||
pthread_mutex_unlock(&g_atfork_list_mutex);
|
||||
|
||||
return 0;
|
||||
@@ -198,9 +216,21 @@ extern "C" int __register_atfork(void (*prepare)(void), void (*parent)(void),
|
||||
|
||||
extern "C" __LIBC_HIDDEN__ void __unregister_atfork(void* dso) {
|
||||
pthread_mutex_lock(&g_atfork_list_mutex);
|
||||
+
|
||||
+ size_t page_size = getpagesize();
|
||||
+
|
||||
+ for (atfork_t* page_it = page_list; page_it; page_it = page_it->next) {
|
||||
+ mprotect(page_it, page_size, PROT_READ|PROT_WRITE);
|
||||
+ }
|
||||
+
|
||||
g_atfork_list.remove_if([&](const atfork_t* entry) {
|
||||
return entry->dso_handle == dso;
|
||||
});
|
||||
+
|
||||
+ for (atfork_t* page_it = page_list; page_it; page_it = page_it->next) {
|
||||
+ mprotect(page_it, page_size, PROT_READ);
|
||||
+ }
|
||||
+
|
||||
pthread_mutex_unlock(&g_atfork_list_mutex);
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
From 1ebb1654556ed74d63e43fe7dbbceae5b20f569f Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Sat, 7 Feb 2015 20:14:24 -0500
|
||||
Subject: [PATCH] add memory protection for at_quick_exit
|
||||
|
||||
---
|
||||
.../lib/libc/stdlib/quick_exit.c | 41 ++++++++++++++++---
|
||||
1 file changed, 36 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/quick_exit.c b/libc/upstream-freebsd/lib/libc/stdlib/quick_exit.c
|
||||
index ef8cdb1b40..b23d8642ae 100644
|
||||
--- a/libc/upstream-freebsd/lib/libc/stdlib/quick_exit.c
|
||||
+++ b/libc/upstream-freebsd/lib/libc/stdlib/quick_exit.c
|
||||
@@ -28,6 +28,10 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
+#include <sys/mman.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include "private/bionic_prctl.h"
|
||||
|
||||
/**
|
||||
* Linked list of quick exit handlers. This is simpler than the atexit()
|
||||
@@ -39,6 +43,10 @@ struct quick_exit_handler {
|
||||
void (*cleanup)(void);
|
||||
};
|
||||
|
||||
+static struct quick_exit_handler *pool_page;
|
||||
+static struct quick_exit_handler *pool;
|
||||
+static size_t pool_size;
|
||||
+
|
||||
/**
|
||||
* Lock protecting the handlers list.
|
||||
*/
|
||||
@@ -51,16 +59,39 @@ static struct quick_exit_handler *handlers;
|
||||
int
|
||||
at_quick_exit(void (*func)(void))
|
||||
{
|
||||
+ size_t page_size = getpagesize();
|
||||
struct quick_exit_handler *h;
|
||||
-
|
||||
- h = malloc(sizeof(*h));
|
||||
|
||||
- if (NULL == h)
|
||||
- return (1);
|
||||
- h->cleanup = func;
|
||||
pthread_mutex_lock(&atexit_mutex);
|
||||
+
|
||||
+ if (pool_size < sizeof(*h)) {
|
||||
+ void *ptr = mmap(NULL, page_size, PROT_READ|PROT_WRITE,
|
||||
+ MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
|
||||
+ if (ptr == MAP_FAILED) {
|
||||
+ pthread_mutex_unlock(&atexit_mutex);
|
||||
+ return (1);
|
||||
+ }
|
||||
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, ptr, page_size,
|
||||
+ "at_quick_exit handlers");
|
||||
+ pool_page = pool = ptr;
|
||||
+ pool_size = page_size;
|
||||
+ } else {
|
||||
+ if (mprotect(pool_page, page_size, PROT_READ|PROT_WRITE)) {
|
||||
+ pthread_mutex_unlock(&atexit_mutex);
|
||||
+ return (1);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ h = pool++;
|
||||
+ pool_size -= sizeof(*h);
|
||||
+
|
||||
+ h->cleanup = func;
|
||||
+
|
||||
h->next = handlers;
|
||||
handlers = h;
|
||||
+
|
||||
+ mprotect(pool_page, page_size, PROT_READ);
|
||||
+
|
||||
pthread_mutex_unlock(&atexit_mutex);
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
From 488ba483cf9ad195fda33b3250115a308bf03f75 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Wed, 27 Jan 2016 18:02:15 -0500
|
||||
Subject: [PATCH] add XOR mangling mitigation for thread-local dtors
|
||||
|
||||
---
|
||||
libc/bionic/__cxa_thread_atexit_impl.cpp | 8 +++++---
|
||||
libc/bionic/libc_init_common.cpp | 2 ++
|
||||
libc/private/bionic_globals.h | 1 +
|
||||
3 files changed, 8 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libc/bionic/__cxa_thread_atexit_impl.cpp b/libc/bionic/__cxa_thread_atexit_impl.cpp
|
||||
index 99077c101d..74608513ef 100644
|
||||
--- a/libc/bionic/__cxa_thread_atexit_impl.cpp
|
||||
+++ b/libc/bionic/__cxa_thread_atexit_impl.cpp
|
||||
@@ -13,15 +13,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
+#include <stdint.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <private/bionic_defs.h>
|
||||
+#include <private/bionic_globals.h>
|
||||
|
||||
#include "pthread_internal.h"
|
||||
|
||||
class thread_local_dtor {
|
||||
public:
|
||||
- void (*func) (void *);
|
||||
+ uintptr_t func;
|
||||
void *arg;
|
||||
void *dso_handle; // unused...
|
||||
thread_local_dtor* next;
|
||||
@@ -35,7 +37,7 @@ __BIONIC_WEAK_FOR_NATIVE_BRIDGE
|
||||
int __cxa_thread_atexit_impl(void (*func) (void *), void *arg, void *dso_handle) {
|
||||
thread_local_dtor* dtor = new thread_local_dtor();
|
||||
|
||||
- dtor->func = func;
|
||||
+ dtor->func = __libc_globals->dtor_cookie ^ reinterpret_cast<uintptr_t>(func);
|
||||
dtor->arg = arg;
|
||||
dtor->dso_handle = dso_handle;
|
||||
|
||||
@@ -54,7 +56,7 @@ extern "C" __LIBC_HIDDEN__ void __cxa_thread_finalize() {
|
||||
thread_local_dtor* current = thread->thread_local_dtors;
|
||||
thread->thread_local_dtors = current->next;
|
||||
|
||||
- current->func(current->arg);
|
||||
+ (reinterpret_cast<void (*)(void*)>(__libc_globals->dtor_cookie ^ current->func))(current->arg);
|
||||
if (__loader_remove_thread_local_dtor != nullptr) {
|
||||
__loader_remove_thread_local_dtor(current->dso_handle);
|
||||
}
|
||||
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
|
||||
index 2396c36782..47555c598a 100644
|
||||
--- a/libc/bionic/libc_init_common.cpp
|
||||
+++ b/libc/bionic/libc_init_common.cpp
|
||||
@@ -45,6 +45,7 @@
|
||||
|
||||
#include "private/KernelArgumentBlock.h"
|
||||
#include "private/WriteProtected.h"
|
||||
+#include "private/bionic_arc4random.h"
|
||||
#include "private/bionic_auxv.h"
|
||||
#include "private/bionic_defs.h"
|
||||
#include "private/bionic_globals.h"
|
||||
@@ -91,6 +92,7 @@ void __libc_init_globals(KernelArgumentBlock& args) {
|
||||
__libc_globals.mutate([&args](libc_globals* globals) {
|
||||
__libc_init_vdso(globals, args);
|
||||
__libc_init_setjmp_cookie(globals, args);
|
||||
+ arc4random_buf(&globals->dtor_cookie, sizeof(globals->dtor_cookie));
|
||||
});
|
||||
}
|
||||
|
||||
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
|
||||
index 94dd7e8590..0361f4ed72 100644
|
||||
--- a/libc/private/bionic_globals.h
|
||||
+++ b/libc/private/bionic_globals.h
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
struct libc_globals {
|
||||
vdso_entry vdso[VDSO_END];
|
||||
+ long dtor_cookie;
|
||||
long setjmp_cookie;
|
||||
MallocDispatch malloc_dispatch;
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
From f9351d884bddaf126a8fc45c8cb14e7ca2cf463b Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Fri, 29 Jan 2016 20:20:09 -0500
|
||||
Subject: [PATCH] use a better pthread_attr junk filling pattern
|
||||
|
||||
Guarantee that junk filled pointers will fault, at least on pure 64-bit.
|
||||
---
|
||||
libc/bionic/pthread_attr.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libc/bionic/pthread_attr.cpp b/libc/bionic/pthread_attr.cpp
|
||||
index 93177f15c8..692bcf162b 100644
|
||||
--- a/libc/bionic/pthread_attr.cpp
|
||||
+++ b/libc/bionic/pthread_attr.cpp
|
||||
@@ -53,7 +53,7 @@ int pthread_attr_init(pthread_attr_t* attr) {
|
||||
|
||||
__BIONIC_WEAK_FOR_NATIVE_BRIDGE
|
||||
int pthread_attr_destroy(pthread_attr_t* attr) {
|
||||
- memset(attr, 0x42, sizeof(pthread_attr_t));
|
||||
+ memset(attr, 0xdf, sizeof(pthread_attr_t));
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
From 85e5bca0a525a1cb8142aa092286ae3424983dd5 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Fri, 11 Dec 2015 01:52:08 -0500
|
||||
Subject: [PATCH] move pthread_internal_t out of the stack mapping
|
||||
|
||||
[TODO: guard pages]
|
||||
---
|
||||
libc/bionic/pthread_create.cpp | 20 +++++++++++---------
|
||||
libc/bionic/pthread_exit.cpp | 7 +++++--
|
||||
libc/bionic/pthread_internal.cpp | 1 +
|
||||
3 files changed, 17 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
|
||||
index 8825c6f240..e70af04094 100644
|
||||
--- a/libc/bionic/pthread_create.cpp
|
||||
+++ b/libc/bionic/pthread_create.cpp
|
||||
@@ -191,7 +191,6 @@ static int __allocate_thread(pthread_attr_t* attr, pthread_internal_t** threadp,
|
||||
// The caller didn't provide a stack, so allocate one.
|
||||
// Make sure the stack size and guard size are multiples of PAGE_SIZE.
|
||||
if (__builtin_add_overflow(attr->stack_size, attr->guard_size, &mmap_size)) return EAGAIN;
|
||||
- if (__builtin_add_overflow(mmap_size, sizeof(pthread_internal_t), &mmap_size)) return EAGAIN;
|
||||
mmap_size = __BIONIC_ALIGN(mmap_size, PAGE_SIZE);
|
||||
attr->guard_size = __BIONIC_ALIGN(attr->guard_size, PAGE_SIZE);
|
||||
attr->stack_base = __create_thread_mapped_space(mmap_size, attr->guard_size);
|
||||
@@ -210,21 +209,23 @@ static int __allocate_thread(pthread_attr_t* attr, pthread_internal_t** threadp,
|
||||
// thread stack (including guard)
|
||||
|
||||
// To safely access the pthread_internal_t and thread stack, we need to find a 16-byte aligned boundary.
|
||||
- stack_top = reinterpret_cast<uint8_t*>(
|
||||
- (reinterpret_cast<uintptr_t>(stack_top) - sizeof(pthread_internal_t)) & ~0xf);
|
||||
-
|
||||
- pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(stack_top);
|
||||
- if (mmap_size == 0) {
|
||||
- // If thread was not allocated by mmap(), it may not have been cleared to zero.
|
||||
- // So assume the worst and zero it.
|
||||
- memset(thread, 0, sizeof(pthread_internal_t));
|
||||
+ stack_top = reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(stack_top) & ~0xf);
|
||||
+
|
||||
+ pthread_internal_t* thread = static_cast<pthread_internal_t*>(
|
||||
+ mmap(nullptr, sizeof(pthread_internal_t), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
|
||||
+ -1, 0));
|
||||
+ if (thread == MAP_FAILED) {
|
||||
+ if (thread->mmap_size != 0) munmap(thread->attr.stack_base, thread->mmap_size);
|
||||
+ return EAGAIN;
|
||||
}
|
||||
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, thread, sizeof(pthread_internal_t), "pthread_internal_t");
|
||||
attr->stack_size = stack_top - reinterpret_cast<uint8_t*>(attr->stack_base);
|
||||
|
||||
thread->mmap_size = mmap_size;
|
||||
thread->attr = *attr;
|
||||
if (!__init_tls(thread)) {
|
||||
if (thread->mmap_size != 0) munmap(thread->attr.stack_base, thread->mmap_size);
|
||||
+ munmap(thread, sizeof(pthread_internal_t));
|
||||
return EAGAIN;
|
||||
}
|
||||
__init_thread_stack_guard(thread);
|
||||
@@ -313,6 +314,7 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
|
||||
if (thread->mmap_size != 0) {
|
||||
munmap(thread->attr.stack_base, thread->mmap_size);
|
||||
}
|
||||
+ munmap(thread, sizeof(pthread_internal_t));
|
||||
async_safe_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: clone failed: %s",
|
||||
strerror(clone_errno));
|
||||
return clone_errno;
|
||||
diff --git a/libc/bionic/pthread_exit.cpp b/libc/bionic/pthread_exit.cpp
|
||||
index f1b65fdf7a..fe26696baf 100644
|
||||
--- a/libc/bionic/pthread_exit.cpp
|
||||
+++ b/libc/bionic/pthread_exit.cpp
|
||||
@@ -118,7 +118,8 @@ void pthread_exit(void* return_value) {
|
||||
// pthread_internal_t is freed below with stack, not here.
|
||||
__pthread_internal_remove(thread);
|
||||
|
||||
- if (thread->mmap_size != 0) {
|
||||
+ size_t mmap_size = thread->mmap_size;
|
||||
+ if (mmap_size != 0) {
|
||||
// We need to free mapped space for detached threads when they exit.
|
||||
// That's not something we can do in C.
|
||||
|
||||
@@ -126,7 +127,9 @@ void pthread_exit(void* return_value) {
|
||||
// That's one last thing we can do before dropping to assembler.
|
||||
ScopedSignalBlocker ssb;
|
||||
__pthread_unmap_tls(thread);
|
||||
- _exit_with_stack_teardown(thread->attr.stack_base, thread->mmap_size);
|
||||
+ void* stack_base = thread->attr.stack_base;
|
||||
+ munmap(thread, sizeof(pthread_internal_t));
|
||||
+ _exit_with_stack_teardown(stack_base, mmap_size);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/libc/bionic/pthread_internal.cpp b/libc/bionic/pthread_internal.cpp
|
||||
index 829194cc71..b5de202487 100644
|
||||
--- a/libc/bionic/pthread_internal.cpp
|
||||
+++ b/libc/bionic/pthread_internal.cpp
|
||||
@@ -91,6 +91,7 @@ static void __pthread_internal_free(pthread_internal_t* thread) {
|
||||
// Free mapped space, including thread stack and pthread_internal_t.
|
||||
munmap(thread->attr.stack_base, thread->mmap_size);
|
||||
}
|
||||
+ munmap(thread, sizeof(pthread_internal_t));
|
||||
}
|
||||
|
||||
void __pthread_internal_remove_and_free(pthread_internal_t* thread) {
|
|
@ -0,0 +1,74 @@
|
|||
From a3a22a63d2cf265d5edc8cf613484e13fd03e19d Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Sun, 8 Feb 2015 01:18:54 -0500
|
||||
Subject: [PATCH] replace brk and sbrk with stubs
|
||||
|
||||
Pretend that there is never room to grow the heap in order to prevent
|
||||
usage of these unsafe legacy functions. There are likely no users of
|
||||
these in practice as it is inherently broken to use them outside of
|
||||
malloc.
|
||||
---
|
||||
libc/bionic/brk.cpp | 48 ++++++++-------------------------------------
|
||||
1 file changed, 8 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/libc/bionic/brk.cpp b/libc/bionic/brk.cpp
|
||||
index e1a4b05345..ef93055139 100644
|
||||
--- a/libc/bionic/brk.cpp
|
||||
+++ b/libc/bionic/brk.cpp
|
||||
@@ -29,48 +29,16 @@
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
-#if defined(__LP64__)
|
||||
-static void* __bionic_brk;
|
||||
-#else
|
||||
-void* __bionic_brk; // Accidentally exported by the NDK.
|
||||
+#if !defined(__LP64__)
|
||||
+void* __bionic_brk = reinterpret_cast<void*>(-1); // Accidentally exported by the NDK.
|
||||
#endif
|
||||
|
||||
-extern "C" void* __brk(void* __addr);
|
||||
-
|
||||
-int brk(void* end_data) {
|
||||
- __bionic_brk = __brk(end_data);
|
||||
- if (__bionic_brk < end_data) {
|
||||
- errno = ENOMEM;
|
||||
- return -1;
|
||||
- }
|
||||
- return 0;
|
||||
+int brk(void*) {
|
||||
+ errno = ENOMEM;
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
-void* sbrk(ptrdiff_t increment) {
|
||||
- // Initialize __bionic_brk if necessary.
|
||||
- if (__bionic_brk == NULL) {
|
||||
- __bionic_brk = __brk(NULL);
|
||||
- }
|
||||
-
|
||||
- // Don't ask the kernel if we already know the answer.
|
||||
- if (increment == 0) {
|
||||
- return __bionic_brk;
|
||||
- }
|
||||
-
|
||||
- // Avoid overflow.
|
||||
- uintptr_t old_brk = reinterpret_cast<uintptr_t>(__bionic_brk);
|
||||
- if ((increment > 0 && static_cast<uintptr_t>(increment) > (UINTPTR_MAX - old_brk)) ||
|
||||
- (increment < 0 && static_cast<uintptr_t>(-increment) > old_brk)) {
|
||||
- errno = ENOMEM;
|
||||
- return reinterpret_cast<void*>(-1);
|
||||
- }
|
||||
-
|
||||
- void* desired_brk = reinterpret_cast<void*>(old_brk + increment);
|
||||
- __bionic_brk = __brk(desired_brk);
|
||||
- if (__bionic_brk < desired_brk) {
|
||||
- errno = ENOMEM;
|
||||
- return reinterpret_cast<void*>(-1);
|
||||
- }
|
||||
-
|
||||
- return reinterpret_cast<void*>(old_brk);
|
||||
+void* sbrk(ptrdiff_t) {
|
||||
+ errno = ENOMEM;
|
||||
+ return reinterpret_cast<void*>(-1);
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
From 7444dbc3cf11285fb94d5d00913016afd7b0dff2 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Mon, 4 Mar 2019 04:26:04 -0500
|
||||
Subject: [PATCH] use blocking getrandom and avoid urandom fallback
|
||||
|
||||
---
|
||||
libc/bionic/getentropy.cpp | 30 ++----------------------------
|
||||
1 file changed, 2 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/libc/bionic/getentropy.cpp b/libc/bionic/getentropy.cpp
|
||||
index 2c6e417b87..ad49039af1 100644
|
||||
--- a/libc/bionic/getentropy.cpp
|
||||
+++ b/libc/bionic/getentropy.cpp
|
||||
@@ -31,26 +31,6 @@
|
||||
#include <sys/random.h>
|
||||
#include <unistd.h>
|
||||
|
||||
-static int getentropy_urandom(void* buffer, size_t buffer_size, int saved_errno) {
|
||||
- int fd = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY | O_NOFOLLOW | O_CLOEXEC, 0));
|
||||
- if (fd == -1) return -1;
|
||||
-
|
||||
- size_t collected = 0;
|
||||
- while (collected < buffer_size) {
|
||||
- ssize_t count = TEMP_FAILURE_RETRY(read(fd, static_cast<char*>(buffer) + collected,
|
||||
- buffer_size - collected));
|
||||
- if (count == -1) {
|
||||
- close(fd);
|
||||
- return -1;
|
||||
- }
|
||||
- collected += count;
|
||||
- }
|
||||
-
|
||||
- close(fd);
|
||||
- errno = saved_errno;
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
int getentropy(void* buffer, size_t buffer_size) {
|
||||
if (buffer_size > 256) {
|
||||
errno = EIO;
|
||||
@@ -62,15 +42,9 @@ int getentropy(void* buffer, size_t buffer_size) {
|
||||
size_t collected = 0;
|
||||
while (collected < buffer_size) {
|
||||
long count = TEMP_FAILURE_RETRY(getrandom(static_cast<char*>(buffer) + collected,
|
||||
- buffer_size - collected, GRND_NONBLOCK));
|
||||
+ buffer_size - collected, 0));
|
||||
if (count == -1) {
|
||||
- // EAGAIN: there isn't enough entropy right now.
|
||||
- // ENOSYS/EINVAL: getrandom(2) or GRND_NONBLOCK isn't supported.
|
||||
- // EFAULT: `buffer` is invalid.
|
||||
- // Try /dev/urandom regardless because it can't hurt,
|
||||
- // and we don't need to optimize the EFAULT case.
|
||||
- // See http://b/33059407 and http://b/67015565.
|
||||
- return getentropy_urandom(buffer, buffer_size, saved_errno);
|
||||
+ return -1;
|
||||
}
|
||||
collected += count;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
From dcd3b72ac9cac79d4322a17be150c46f65ffb3cd Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Mon, 19 Sep 2016 07:57:43 -0400
|
||||
Subject: [PATCH] fix undefined out-of-bounds accesses in sched.h
|
||||
|
||||
---
|
||||
libc/include/sched.h | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libc/include/sched.h b/libc/include/sched.h
|
||||
index de6969f863..fd333a023a 100644
|
||||
--- a/libc/include/sched.h
|
||||
+++ b/libc/include/sched.h
|
||||
@@ -71,7 +71,10 @@ int setns(int __fd, int __ns_type) __INTRODUCED_IN(21);
|
||||
#define __CPU_MASK(x) ((__CPU_BITTYPE)1 << ((x) & (__CPU_BITS - 1)))
|
||||
|
||||
typedef struct {
|
||||
- __CPU_BITTYPE __bits[ CPU_SETSIZE / __CPU_BITS ];
|
||||
+ union {
|
||||
+ __CPU_BITTYPE __bits_minimum[ CPU_SETSIZE / __CPU_BITS ];
|
||||
+ __CPU_BITTYPE __bits[0];
|
||||
+ };
|
||||
} cpu_set_t;
|
||||
|
||||
int sched_setaffinity(pid_t __pid, size_t __set_size, const cpu_set_t* __set) __INTRODUCED_IN(12);
|
|
@ -0,0 +1,46 @@
|
|||
From 543e1df342cdd8720ce967d990ca28a2b9c26af2 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Sat, 19 Nov 2016 09:56:14 -0500
|
||||
Subject: [PATCH] stop implicitly marking mappings as mergeable
|
||||
|
||||
---
|
||||
libc/bionic/mmap.cpp | 19 +------------------
|
||||
1 file changed, 1 insertion(+), 18 deletions(-)
|
||||
|
||||
diff --git a/libc/bionic/mmap.cpp b/libc/bionic/mmap.cpp
|
||||
index 35033199ae..c081068928 100644
|
||||
--- a/libc/bionic/mmap.cpp
|
||||
+++ b/libc/bionic/mmap.cpp
|
||||
@@ -39,8 +39,6 @@ extern "C" void* __mmap2(void*, size_t, int, int, int, size_t);
|
||||
|
||||
#define MMAP2_SHIFT 12 // 2**12 == 4096
|
||||
|
||||
-static bool kernel_has_MADV_MERGEABLE = true;
|
||||
-
|
||||
void* mmap64(void* addr, size_t size, int prot, int flags, int fd, off64_t offset) {
|
||||
if (offset < 0 || (offset & ((1UL << MMAP2_SHIFT)-1)) != 0) {
|
||||
errno = EINVAL;
|
||||
@@ -54,22 +52,7 @@ void* mmap64(void* addr, size_t size, int prot, int flags, int fd, off64_t offse
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
- bool is_private_anonymous =
|
||||
- (flags & (MAP_PRIVATE | MAP_ANONYMOUS)) == (MAP_PRIVATE | MAP_ANONYMOUS);
|
||||
- bool is_stack_or_grows_down = (flags & (MAP_STACK | MAP_GROWSDOWN)) != 0;
|
||||
-
|
||||
- void* result = __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);
|
||||
-
|
||||
- if (result != MAP_FAILED && kernel_has_MADV_MERGEABLE &&
|
||||
- is_private_anonymous && !is_stack_or_grows_down) {
|
||||
- ErrnoRestorer errno_restorer;
|
||||
- int rc = madvise(result, size, MADV_MERGEABLE);
|
||||
- if (rc == -1 && errno == EINVAL) {
|
||||
- kernel_has_MADV_MERGEABLE = false;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return result;
|
||||
+ return __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);
|
||||
}
|
||||
|
||||
void* mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset) {
|
|
@ -0,0 +1,39 @@
|
|||
From 611e5691f7e48aba8529e49b22885021f322b31e Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Sat, 16 Jul 2016 23:55:16 -0400
|
||||
Subject: [PATCH] replace VLA formatting buffer with dprintf
|
||||
|
||||
---
|
||||
libc/bionic/bionic_systrace.cpp | 10 +---------
|
||||
1 file changed, 1 insertion(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libc/bionic/bionic_systrace.cpp b/libc/bionic/bionic_systrace.cpp
|
||||
index bac3d88021..076e10dbfb 100644
|
||||
--- a/libc/bionic/bionic_systrace.cpp
|
||||
+++ b/libc/bionic/bionic_systrace.cpp
|
||||
@@ -26,8 +26,6 @@
|
||||
|
||||
#include <cutils/trace.h> // For ATRACE_TAG_BIONIC.
|
||||
|
||||
-#define WRITE_OFFSET 32
|
||||
-
|
||||
static Lock g_lock;
|
||||
static CachedProperty g_debug_atrace_tags_enableflags("debug.atrace.tags.enableflags");
|
||||
static uint64_t g_tags;
|
||||
@@ -61,15 +59,9 @@ void bionic_trace_begin(const char* message) {
|
||||
return;
|
||||
}
|
||||
|
||||
- // If bionic tracing has been enabled, then write the message to the
|
||||
- // kernel trace_marker.
|
||||
- int length = strlen(message);
|
||||
- char buf[length + WRITE_OFFSET];
|
||||
- size_t len = snprintf(buf, length + WRITE_OFFSET, "B|%d|%s", getpid(), message);
|
||||
-
|
||||
// Tracing may stop just after checking property and before writing the message.
|
||||
// So the write is acceptable to fail. See b/20666100.
|
||||
- TEMP_FAILURE_RETRY(write(trace_marker_fd, buf, len));
|
||||
+ dprintf(trace_marker_fd, "B|%d|%s", getpid(), message);
|
||||
}
|
||||
|
||||
void bionic_trace_end() {
|
|
@ -0,0 +1,25 @@
|
|||
From 8de97ce864cc781d077160a8efd4902d4338078c Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Fri, 17 Jul 2015 21:32:05 -0400
|
||||
Subject: [PATCH] increase default pthread stack to 8MiB on 64-bit
|
||||
|
||||
---
|
||||
libc/bionic/pthread_internal.h | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
|
||||
index 9bdf9cdf0c..d59a545459 100644
|
||||
--- a/libc/bionic/pthread_internal.h
|
||||
+++ b/libc/bionic/pthread_internal.h
|
||||
@@ -164,7 +164,11 @@ __LIBC_HIDDEN__ void pthread_key_clean_all(void);
|
||||
// stack overflows, we subtracted the same amount we were using there
|
||||
// from the default thread stack size. This should keep memory usage
|
||||
// roughly constant.
|
||||
+#ifdef __LP64__
|
||||
+#define PTHREAD_STACK_SIZE_DEFAULT ((8 * 1024 * 1024) - SIGNAL_STACK_SIZE_WITHOUT_GUARD)
|
||||
+#else
|
||||
#define PTHREAD_STACK_SIZE_DEFAULT ((1 * 1024 * 1024) - SIGNAL_STACK_SIZE_WITHOUT_GUARD)
|
||||
+#endif
|
||||
|
||||
// Leave room for a guard page in the internally created signal stacks.
|
||||
#define SIGNAL_STACK_SIZE (SIGNAL_STACK_SIZE_WITHOUT_GUARD + PTHREAD_GUARD_SIZE)
|
|
@ -0,0 +1,47 @@
|
|||
From a47571704245e5514795f35bbcffdb8a533e738a Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Sat, 1 Oct 2016 05:11:44 -0400
|
||||
Subject: [PATCH] make __stack_chk_guard read-only at runtime
|
||||
|
||||
---
|
||||
libc/bionic/__libc_init_main_thread.cpp | 14 +++++++++++---
|
||||
1 file changed, 11 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
|
||||
index efa7dee57b..78d25fd977 100644
|
||||
--- a/libc/bionic/__libc_init_main_thread.cpp
|
||||
+++ b/libc/bionic/__libc_init_main_thread.cpp
|
||||
@@ -28,22 +28,30 @@
|
||||
|
||||
#include "libc_init_common.h"
|
||||
|
||||
+#include <limits.h>
|
||||
+#include <sys/mman.h>
|
||||
+
|
||||
+#include <async_safe/log.h>
|
||||
+
|
||||
#include "private/KernelArgumentBlock.h"
|
||||
#include "private/bionic_arc4random.h"
|
||||
#include "private/bionic_auxv.h"
|
||||
#include "private/bionic_defs.h"
|
||||
#include "private/bionic_globals.h"
|
||||
-#include "private/bionic_ssp.h"
|
||||
#include "pthread_internal.h"
|
||||
|
||||
extern "C" int __set_tls(void* ptr);
|
||||
extern "C" int __set_tid_address(int* tid_address);
|
||||
|
||||
// Declared in "private/bionic_ssp.h".
|
||||
-uintptr_t __stack_chk_guard = 0;
|
||||
+__attribute__((aligned(PAGE_SIZE)))
|
||||
+uintptr_t __stack_chk_guard[PAGE_SIZE / sizeof(uintptr_t)] = {0};
|
||||
|
||||
void __libc_init_global_stack_chk_guard(KernelArgumentBlock& args) {
|
||||
- __libc_safe_arc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard), args);
|
||||
+ __libc_safe_arc4random_buf(&__stack_chk_guard[0], sizeof(__stack_chk_guard[0]), args);
|
||||
+ if (mprotect(__stack_chk_guard, sizeof(__stack_chk_guard), PROT_READ) == -1) {
|
||||
+ async_safe_fatal("mprotect __stack_chk_guard: %s", strerror(errno));
|
||||
+ }
|
||||
}
|
||||
|
||||
// Setup for the main thread. For dynamic executables, this is called by the
|
|
@ -0,0 +1,34 @@
|
|||
From 7f0947cc0e4fc52a41ef8ecfba892f5534e1fee5 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Sun, 12 Mar 2017 17:49:13 -0400
|
||||
Subject: [PATCH] on 64-bit, zero the leading stack canary byte
|
||||
|
||||
This reduces entropy of the canary from 64-bit to 56-bit in exchange for
|
||||
mitigating non-terminated C string overflows.
|
||||
---
|
||||
libc/bionic/__libc_init_main_thread.cpp | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
|
||||
index 78d25fd977..ae2245829d 100644
|
||||
--- a/libc/bionic/__libc_init_main_thread.cpp
|
||||
+++ b/libc/bionic/__libc_init_main_thread.cpp
|
||||
@@ -47,8 +47,18 @@ extern "C" int __set_tid_address(int* tid_address);
|
||||
__attribute__((aligned(PAGE_SIZE)))
|
||||
uintptr_t __stack_chk_guard[PAGE_SIZE / sizeof(uintptr_t)] = {0};
|
||||
|
||||
+#if __LP64__
|
||||
+static const uintptr_t canary_mask = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ?
|
||||
+ 0xffffffffffffff00UL :
|
||||
+ 0x00ffffffffffffffUL;
|
||||
+#endif
|
||||
+
|
||||
void __libc_init_global_stack_chk_guard(KernelArgumentBlock& args) {
|
||||
__libc_safe_arc4random_buf(&__stack_chk_guard[0], sizeof(__stack_chk_guard[0]), args);
|
||||
+#if __LP64__
|
||||
+ // Sacrifice 8 bits of entropy on 64-bit to mitigate non-terminated C string overflows
|
||||
+ __stack_chk_guard[0] &= canary_mask;
|
||||
+#endif
|
||||
if (mprotect(__stack_chk_guard, sizeof(__stack_chk_guard), PROT_READ) == -1) {
|
||||
async_safe_fatal("mprotect __stack_chk_guard: %s", strerror(errno));
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
From abdf523d26450814fc3f5c211f3baa643c48bae3 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Micay <danielmicay@gmail.com>
|
||||
Date: Fri, 6 Feb 2015 11:41:57 -0500
|
||||
Subject: [PATCH] zero sensitive information with explicit_bzero
|
||||
|
||||
---
|
||||
init/security.cpp | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/init/security.cpp b/init/security.cpp
|
||||
index a3494a280bd..4b6c918ab30 100644
|
||||
--- a/init/security.cpp
|
||||
+++ b/init/security.cpp
|
||||
@@ -73,6 +73,7 @@ Result<Success> MixHwrngIntoLinuxRngAction(const BuiltinArguments&) {
|
||||
}
|
||||
|
||||
chunk_size = TEMP_FAILURE_RETRY(write(urandom_fd, buf, chunk_size));
|
||||
+ explicit_bzero(buf, chunk_size);
|
||||
if (chunk_size == -1) {
|
||||
return ErrnoError() << "Failed to write to /dev/urandom";
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue