From 181519cf3879b040e984f14fcf807cae2469b15a Mon Sep 17 00:00:00 2001 From: Tad Date: Tue, 15 Mar 2022 16:34:57 -0400 Subject: [PATCH] Add bionic hardening patchsets from GrapheneOS 11 https://github.com/GrapheneOS/platform_system_core/commit/b3a0c2c5db28852b6d485542c8a4f1649a256892 11 https://github.com/GrapheneOS/platform_bionic/commit/5412c371955014eee8b2246b386ae7f539bac09e #explicit zero 11 https://github.com/GrapheneOS/platform_bionic/commit/31456ac632903235e14500af8b5d7dff2d25d724 #brk 11 https://github.com/GrapheneOS/platform_bionic/commit/58ebc243ea3085056e6aba765d879807fa1a46d6 #random 11 https://github.com/GrapheneOS/platform_bionic/commit/5323b39f7ec1fce2d788f1c8a2c28cfd32d5ccc4 #undefined 11 https://github.com/GrapheneOS/platform_bionic/commit/6a91d9dddb01964134e50cc73f6f158706da800a #merge 11 https://github.com/GrapheneOS/platform_bionic/commit/a042b5a0bada9933b7c488003e8f9d8d0d195525 #vla formatting 11 https://github.com/GrapheneOS/platform_bionic/commit/9ec639de1bec2f655bdfc0750e363a6f8de31c4a #pthread 11 https://github.com/GrapheneOS/platform_bionic/commit/49571a0a496539b9af763b8ef30c5b5db57c8be7 #read only 11 https://github.com/GrapheneOS/platform_bionic/commit/149cc5ccb870640b2536b6bd5dfa1292f9dd6178 #zero 11 https://github.com/GrapheneOS/platform_bionic/commit/2e613ccbe7a6b2aa8f1688ed8493267d12c66d23 #fork mmap 11 https://github.com/GrapheneOS/platform_bionic/commit/e239c7dff88bbc37a3e902a695565fdbf6ed0b08 #memprot pthread 11 https://github.com/GrapheneOS/platform_bionic/commit/0b03d92b7f2dc5f12211037e99821ccead27a687 #xor 11 https://github.com/GrapheneOS/platform_bionic/commit/de08419b8256ab7daf6ef7c7835348f9aaeb7478 #junk 11 https://github.com/GrapheneOS/platform_bionic/commit/897d4903e24c9f6b772539e9f8e0bf3520ed8838 #guard 11 https://github.com/GrapheneOS/platform_bionic/commit/648cd68ca3ffefe685ae6acdae17171c8acfa75b #ptrhread guard 11 https://github.com/GrapheneOS/platform_bionic/commit/0bc4dbcbd27c7f48713913101fb3c868c215c1a3 #stack rand 10 https://github.com/GrapheneOS/platform_system_core/commit/aa9cc05d07a5855fcae2d9f21dd9672543eafbb3 10 https://github.com/GrapheneOS/platform_bionic/commit/a8cdbb6352e4ff708b791c7f3a976de8a6383105 #explicit zero 10 https://github.com/GrapheneOS/platform_bionic/commit/b28302c668013a5588a6939f0bbced0b7b288cc2 #brk 10 https://github.com/GrapheneOS/platform_bionic/commit/9f8be7d07cc063933f8def97672c7671dd4fc360 #random 10 https://github.com/GrapheneOS/platform_bionic/commit/cb91a7ee3aed607dab2d89f2f6b823bf28ea34a0 #undefined 10 https://github.com/GrapheneOS/platform_bionic/commit/08279e2fdd75d20ede2a56c326604f426557cea4 #merge 10 https://github.com/GrapheneOS/platform_bionic/commit/6a18bd565d9344db5f46f2bb423309dcb134be6e #vla formatting 10 https://github.com/GrapheneOS/platform_bionic/commit/2f392c2d081fad13f61164ab07841818b972f950 #pthread 10 https://github.com/GrapheneOS/platform_bionic/commit/8bbce1bc50f7b0fb210de3ef160542bbb08cdcc0 #read only 10 https://github.com/GrapheneOS/platform_bionic/commit/725f61db82eb41098291ce06445ccfbf5d5b3581 #zero 10 https://github.com/GrapheneOS/platform_bionic/commit/4cd257135f72ceb7ddd32538d2ba579736bf7a12 #fork mmap 10 https://github.com/GrapheneOS/platform_bionic/commit/9220cf622bab1099cbff937d88aa7ce2809bb9d4 #memprot pthread 10 https://github.com/GrapheneOS/platform_bionic/commit/8ef71d1ffd51664bc8d61fd029efa899a87ddc30 #memprot exit 10 https://github.com/GrapheneOS/platform_bionic/commit/0eaef1abbdcbf40c990fcba1bd91401bdd38a9c5 #xor 10 https://github.com/GrapheneOS/platform_bionic/commit/64f1cc2148c1834212f6704ba08b626696501271 #junk 10 https://github.com/GrapheneOS/platform_bionic/commit/5c42a527cf958ca3c81613178618d452e806994f #guard 10 https://github.com/GrapheneOS/platform_bionic/commit/5cc8c34e60dbfeb1fd996bf83bb01a0443d93a8a #pthread guard 10 https://github.com/GrapheneOS/platform_bionic/commit/7f61cc8a1c9abd04094a96959f242b7906fa3127 #stack rand 9 https://github.com/GrapheneOS/platform_system_core/commit/abdf523d26450814fc3f5c211f3baa643c48bae3 9 https://github.com/GrapheneOS/platform_bionic/commit/e4b9b31e6f9ff7eb9d168db6a99a775bf4f669c1 #explicit zero 9 https://github.com/GrapheneOS/platform_bionic/commit/a3a22a63d2cf265d5edc8cf613484e13fd03e19d #brk 9 https://github.com/GrapheneOS/platform_bionic/commit/7444dbc3cf11285fb94d5d00913016afd7b0dff2 #random 9 https://github.com/GrapheneOS/platform_bionic/commit/dcd3b72ac9cac79d4322a17be150c46f65ffb3cd #undefined 9 https://github.com/GrapheneOS/platform_bionic/commit/543e1df342cdd8720ce967d990ca28a2b9c26af2 #merge 9 https://github.com/GrapheneOS/platform_bionic/commit/611e5691f7e48aba8529e49b22885021f322b31e #vla formatting 9 https://github.com/GrapheneOS/platform_bionic/commit/8de97ce864cc781d077160a8efd4902d4338078c #pthread 9 https://github.com/GrapheneOS/platform_bionic/commit/a47571704245e5514795f35bbcffdb8a533e738a #read only 9 https://github.com/GrapheneOS/platform_bionic/commit/7f0947cc0e4fc52a41ef8ecfba892f5534e1fee5 #zero 9 https://github.com/GrapheneOS/platform_bionic/commit/e9751d3370aa44e6ca77843f7c7a7aac67e5bcc0 #fork mmap 9 https://github.com/GrapheneOS/platform_bionic/commit/83cd86d0d522c64726dac41614c00f2534044f73 #memprot pthread 9 https://github.com/GrapheneOS/platform_bionic/commit/1ebb1654556ed74d63e43fe7dbbceae5b20f569f #memprot exit 9 https://github.com/GrapheneOS/platform_bionic/commit/488ba483cf9ad195fda33b3250115a308bf03f75 #xor 9 https://github.com/GrapheneOS/platform_bionic/commit/f9351d884bddaf126a8fc45c8cb14e7ca2cf463b #junk 9 https://github.com/GrapheneOS/platform_bionic/commit/85e5bca0a525a1cb8142aa092286ae3424983dd5 #move Signed-off-by: Tad --- .../0002-Graphene_Bionic_Hardening-1.patch | 163 ++++++++++++++++++ .../0002-Graphene_Bionic_Hardening-10.patch | 85 +++++++++ .../0002-Graphene_Bionic_Hardening-11.patch | 95 ++++++++++ .../0002-Graphene_Bionic_Hardening-12.patch | 80 +++++++++ .../0002-Graphene_Bionic_Hardening-13.patch | 84 +++++++++ .../0002-Graphene_Bionic_Hardening-14.patch | 23 +++ .../0002-Graphene_Bionic_Hardening-15.patch | 101 +++++++++++ .../0002-Graphene_Bionic_Hardening-2.patch | 74 ++++++++ .../0002-Graphene_Bionic_Hardening-3.patch | 58 +++++++ .../0002-Graphene_Bionic_Hardening-4.patch | 25 +++ .../0002-Graphene_Bionic_Hardening-5.patch | 46 +++++ .../0002-Graphene_Bionic_Hardening-6.patch | 39 +++++ .../0002-Graphene_Bionic_Hardening-7.patch | 25 +++ .../0002-Graphene_Bionic_Hardening-8.patch | 47 +++++ .../0002-Graphene_Bionic_Hardening-9.patch | 34 ++++ .../0003-Zero_Sensitive_Info.patch | 21 +++ .../0003-Graphene_Bionic_Hardening-1.patch | 85 +++++++++ .../0003-Graphene_Bionic_Hardening-10.patch | 83 +++++++++ .../0003-Graphene_Bionic_Hardening-11.patch | 94 ++++++++++ .../0003-Graphene_Bionic_Hardening-12.patch | 79 +++++++++ .../0003-Graphene_Bionic_Hardening-13.patch | 84 +++++++++ .../0003-Graphene_Bionic_Hardening-14.patch | 23 +++ .../0003-Graphene_Bionic_Hardening-15.patch | 75 ++++++++ .../0003-Graphene_Bionic_Hardening-16.patch | 57 ++++++ .../0003-Graphene_Bionic_Hardening-17.patch | 97 +++++++++++ .../0003-Graphene_Bionic_Hardening-2.patch | 74 ++++++++ .../0003-Graphene_Bionic_Hardening-3.patch | 58 +++++++ .../0003-Graphene_Bionic_Hardening-4.patch | 25 +++ .../0003-Graphene_Bionic_Hardening-5.patch | 46 +++++ .../0003-Graphene_Bionic_Hardening-6.patch | 39 +++++ .../0003-Graphene_Bionic_Hardening-7.patch | 25 +++ .../0003-Graphene_Bionic_Hardening-8.patch | 58 +++++++ .../0003-Graphene_Bionic_Hardening-9.patch | 40 +++++ .../0003-Zero_Sensitive_Info.patch | 21 +++ .../0002-Graphene_Bionic_Hardening-1.patch | 85 +++++++++ .../0002-Graphene_Bionic_Hardening-10.patch | 84 +++++++++ .../0002-Graphene_Bionic_Hardening-11.patch | 95 ++++++++++ .../0002-Graphene_Bionic_Hardening-12.patch | 85 +++++++++ .../0002-Graphene_Bionic_Hardening-13.patch | 25 +++ .../0002-Graphene_Bionic_Hardening-14.patch | 76 ++++++++ .../0002-Graphene_Bionic_Hardening-15.patch | 58 +++++++ .../0002-Graphene_Bionic_Hardening-16.patch | 98 +++++++++++ .../0002-Graphene_Bionic_Hardening-2.patch | 76 ++++++++ .../0002-Graphene_Bionic_Hardening-3.patch | 55 ++++++ .../0002-Graphene_Bionic_Hardening-4.patch | 26 +++ .../0002-Graphene_Bionic_Hardening-5.patch | 47 +++++ .../0002-Graphene_Bionic_Hardening-6.patch | 40 +++++ .../0002-Graphene_Bionic_Hardening-7.patch | 26 +++ .../0002-Graphene_Bionic_Hardening-8.patch | 59 +++++++ .../0002-Graphene_Bionic_Hardening-9.patch | 42 +++++ .../0004-Zero_Sensitive_Info.patch | 21 +++ Scripts/LineageOS-16.0/Patch.sh | 18 ++ Scripts/LineageOS-17.1/Patch.sh | 20 +++ Scripts/LineageOS-18.1/Patch.sh | 23 ++- Scripts/init.sh | 1 + 55 files changed, 3121 insertions(+), 2 deletions(-) create mode 100644 Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-1.patch create mode 100644 Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-10.patch create mode 100644 Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-11.patch create mode 100644 Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-12.patch create mode 100644 Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-13.patch create mode 100644 Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-14.patch create mode 100644 Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-15.patch create mode 100644 Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-2.patch create mode 100644 Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-3.patch create mode 100644 Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-4.patch create mode 100644 Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-5.patch create mode 100644 Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-6.patch create mode 100644 Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-7.patch create mode 100644 Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-8.patch create mode 100644 Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-9.patch create mode 100644 Patches/LineageOS-16.0/android_system_core/0003-Zero_Sensitive_Info.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-1.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-10.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-11.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-12.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-13.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-14.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-15.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-16.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-17.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-2.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-3.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-4.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-5.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-6.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-7.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-8.patch create mode 100644 Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-9.patch create mode 100644 Patches/LineageOS-17.1/android_system_core/0003-Zero_Sensitive_Info.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-1.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-10.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-11.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-12.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-13.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-14.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-15.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-16.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-2.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-3.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-4.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-5.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-6.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-7.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-8.patch create mode 100644 Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-9.patch create mode 100644 Patches/LineageOS-18.1/android_system_core/0004-Zero_Sensitive_Info.patch diff --git a/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-1.patch b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-1.patch new file mode 100644 index 00000000..083f44aa --- /dev/null +++ b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-1.patch @@ -0,0 +1,163 @@ +From e4b9b31e6f9ff7eb9d168db6a99a775bf4f669c1 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 ++ ++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 , but "ALIGN" isn't something we want to reserve. */ + #define ALIGNBYTES (sizeof(uintptr_t) - 1) + #define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES) diff --git a/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-10.patch b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-10.patch new file mode 100644 index 00000000..0c00c4e8 --- /dev/null +++ b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-10.patch @@ -0,0 +1,85 @@ +From e9751d3370aa44e6ca77843f7c7a7aac67e5bcc0 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 + #include + #include ++#include ++#include + + #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(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(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(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); diff --git a/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-11.patch b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-11.patch new file mode 100644 index 00000000..1b04aa55 --- /dev/null +++ b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-11.patch @@ -0,0 +1,95 @@ +From 83cd86d0d522c64726dac41614c00f2534044f73 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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(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(it); + node->next = pool; + pool = node; + } ++ ++ atfork_t* page_node = reinterpret_cast(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); + } + diff --git a/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-12.patch b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-12.patch new file mode 100644 index 00000000..7fc4098d --- /dev/null +++ b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-12.patch @@ -0,0 +1,80 @@ +From 1ebb1654556ed74d63e43fe7dbbceae5b20f569f Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 + #include ++#include ++#include ++ ++#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); + } diff --git a/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-13.patch b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-13.patch new file mode 100644 index 00000000..94ae806a --- /dev/null +++ b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-13.patch @@ -0,0 +1,84 @@ +From 488ba483cf9ad195fda33b3250115a308bf03f75 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 + #include + + #include ++#include + + #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(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(__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; + }; diff --git a/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-14.patch b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-14.patch new file mode 100644 index 00000000..d104212b --- /dev/null +++ b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-14.patch @@ -0,0 +1,23 @@ +From f9351d884bddaf126a8fc45c8cb14e7ca2cf463b Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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; + } + diff --git a/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-15.patch b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-15.patch new file mode 100644 index 00000000..1b4df241 --- /dev/null +++ b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-15.patch @@ -0,0 +1,101 @@ +From 85e5bca0a525a1cb8142aa092286ae3424983dd5 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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( +- (reinterpret_cast(stack_top) - sizeof(pthread_internal_t)) & ~0xf); +- +- pthread_internal_t* thread = reinterpret_cast(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(reinterpret_cast(stack_top) & ~0xf); ++ ++ pthread_internal_t* thread = static_cast( ++ 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(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) { diff --git a/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-2.patch b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-2.patch new file mode 100644 index 00000000..5c5e8c2e --- /dev/null +++ b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-2.patch @@ -0,0 +1,74 @@ +From a3a22a63d2cf265d5edc8cf613484e13fd03e19d Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 + #include + +-#if defined(__LP64__) +-static void* __bionic_brk; +-#else +-void* __bionic_brk; // Accidentally exported by the NDK. ++#if !defined(__LP64__) ++void* __bionic_brk = reinterpret_cast(-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(__bionic_brk); +- if ((increment > 0 && static_cast(increment) > (UINTPTR_MAX - old_brk)) || +- (increment < 0 && static_cast(-increment) > old_brk)) { +- errno = ENOMEM; +- return reinterpret_cast(-1); +- } +- +- void* desired_brk = reinterpret_cast(old_brk + increment); +- __bionic_brk = __brk(desired_brk); +- if (__bionic_brk < desired_brk) { +- errno = ENOMEM; +- return reinterpret_cast(-1); +- } +- +- return reinterpret_cast(old_brk); ++void* sbrk(ptrdiff_t) { ++ errno = ENOMEM; ++ return reinterpret_cast(-1); + } diff --git a/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-3.patch b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-3.patch new file mode 100644 index 00000000..fd092f9a --- /dev/null +++ b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-3.patch @@ -0,0 +1,58 @@ +From 7444dbc3cf11285fb94d5d00913016afd7b0dff2 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 + #include + +-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(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(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; + } diff --git a/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-4.patch b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-4.patch new file mode 100644 index 00000000..41e39116 --- /dev/null +++ b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-4.patch @@ -0,0 +1,25 @@ +From dcd3b72ac9cac79d4322a17be150c46f65ffb3cd Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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); diff --git a/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-5.patch b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-5.patch new file mode 100644 index 00000000..52053ddd --- /dev/null +++ b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-5.patch @@ -0,0 +1,46 @@ +From 543e1df342cdd8720ce967d990ca28a2b9c26af2 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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) { diff --git a/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-6.patch b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-6.patch new file mode 100644 index 00000000..fa1d300a --- /dev/null +++ b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-6.patch @@ -0,0 +1,39 @@ +From 611e5691f7e48aba8529e49b22885021f322b31e Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 // 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() { diff --git a/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-7.patch b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-7.patch new file mode 100644 index 00000000..14d0b8c4 --- /dev/null +++ b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-7.patch @@ -0,0 +1,25 @@ +From 8de97ce864cc781d077160a8efd4902d4338078c Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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) diff --git a/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-8.patch b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-8.patch new file mode 100644 index 00000000..3fe73971 --- /dev/null +++ b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-8.patch @@ -0,0 +1,47 @@ +From a47571704245e5514795f35bbcffdb8a533e738a Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 ++#include ++ ++#include ++ + #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 diff --git a/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-9.patch b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-9.patch new file mode 100644 index 00000000..bd564491 --- /dev/null +++ b/Patches/LineageOS-16.0/android_bionic/0002-Graphene_Bionic_Hardening-9.patch @@ -0,0 +1,34 @@ +From 7f0947cc0e4fc52a41ef8ecfba892f5534e1fee5 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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)); + } diff --git a/Patches/LineageOS-16.0/android_system_core/0003-Zero_Sensitive_Info.patch b/Patches/LineageOS-16.0/android_system_core/0003-Zero_Sensitive_Info.patch new file mode 100644 index 00000000..aeef46d0 --- /dev/null +++ b/Patches/LineageOS-16.0/android_system_core/0003-Zero_Sensitive_Info.patch @@ -0,0 +1,21 @@ +From abdf523d26450814fc3f5c211f3baa643c48bae3 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 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"; + } diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-1.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-1.patch new file mode 100644 index 00000000..6309f500 --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-1.patch @@ -0,0 +1,85 @@ +From a8cdbb6352e4ff708b791c7f3a976de8a6383105 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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.map.txt | 1 + + libc/upstream-openbsd/android/include/openbsd-compat.h | 2 -- + 5 files changed, 10 insertions(+), 2 deletions(-) + create mode 100644 libc/bionic/explicit_bzero.cpp + +diff --git a/libc/Android.bp b/libc/Android.bp +index a5990288d2..47fccde7e7 100644 +--- a/libc/Android.bp ++++ b/libc/Android.bp +@@ -1041,6 +1041,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 ++ ++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 25f6673a99..6c7b4eba0f 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.map.txt b/libc/libc.map.txt +index 88192239a1..0ec519b9c8 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/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h +index c99e2ce9df..62cb51e9fc 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 , but "ALIGN" isn't something we want to reserve. */ + #define ALIGNBYTES (sizeof(uintptr_t) - 1) + #define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES) diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-10.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-10.patch new file mode 100644 index 00000000..2a11855c --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-10.patch @@ -0,0 +1,83 @@ +From 4cd257135f72ceb7ddd32538d2ba579736bf7a12 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 fb12a3ba74..cc3657f126 100644 +--- a/libc/bionic/pthread_atfork.cpp ++++ b/libc/bionic/pthread_atfork.cpp +@@ -29,6 +29,9 @@ + #include + #include + #include ++#include ++#include ++#include + + #include "private/bionic_macros.h" + +@@ -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(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(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(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); diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-11.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-11.patch new file mode 100644 index 00000000..c4938276 --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-11.patch @@ -0,0 +1,94 @@ +From 9220cf622bab1099cbff937d88aa7ce2809bb9d4 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 cc3657f126..d11dab84a7 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(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(it); + node->next = pool; + pool = node; + } ++ ++ atfork_t* page_node = reinterpret_cast(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,8 +216,20 @@ 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); + } diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-12.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-12.patch new file mode 100644 index 00000000..e5c5f024 --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-12.patch @@ -0,0 +1,79 @@ +From 8ef71d1ffd51664bc8d61fd029efa899a87ddc30 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Sat, 7 Feb 2015 20:14:24 -0500 +Subject: [PATCH] add memory protection for at_quick_exit + +--- + .../lib/libc/stdlib/quick_exit.c | 40 ++++++++++++++++--- + 1 file changed, 35 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..63b54e3fb8 100644 +--- a/libc/upstream-freebsd/lib/libc/stdlib/quick_exit.c ++++ b/libc/upstream-freebsd/lib/libc/stdlib/quick_exit.c +@@ -28,6 +28,9 @@ + + #include + #include ++#include ++#include ++#include + + /** + * Linked list of quick exit handlers. This is simpler than the atexit() +@@ -39,6 +42,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 +58,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); + } diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-13.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-13.patch new file mode 100644 index 00000000..7314e38e --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-13.patch @@ -0,0 +1,84 @@ +From 0eaef1abbdcbf40c990fcba1bd91401bdd38a9c5 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 + #include + + #include ++#include + + #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(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(__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 b229cda2fd..e928c02f1b 100644 +--- a/libc/bionic/libc_init_common.cpp ++++ b/libc/bionic/libc_init_common.cpp +@@ -44,6 +44,7 @@ + #include + + #include "private/WriteProtected.h" ++#include "private/bionic_arc4random.h" + #include "private/bionic_defs.h" + #include "private/bionic_globals.h" + #include "private/bionic_tls.h" +@@ -65,6 +66,7 @@ void __libc_init_globals() { + __libc_globals.mutate([](libc_globals* globals) { + __libc_init_vdso(globals); + __libc_init_setjmp_cookie(globals); ++ arc4random_buf(&globals->dtor_cookie, sizeof(globals->dtor_cookie)); + }); + } + +diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h +index d73079e33d..4c296037b1 100644 +--- a/libc/private/bionic_globals.h ++++ b/libc/private/bionic_globals.h +@@ -43,6 +43,7 @@ + + struct libc_globals { + vdso_entry vdso[VDSO_END]; ++ long dtor_cookie; + long setjmp_cookie; + + // In order to allow a complete switch between dispatch tables without diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-14.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-14.patch new file mode 100644 index 00000000..8a31ddf3 --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-14.patch @@ -0,0 +1,23 @@ +From 64f1cc2148c1834212f6704ba08b626696501271 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 3c4b169eed..a27201706e 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; + } + diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-15.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-15.patch new file mode 100644 index 00000000..860a1a93 --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-15.patch @@ -0,0 +1,75 @@ +From 5c42a527cf958ca3c81613178618d452e806994f Mon Sep 17 00:00:00 2001 +From: Renlord +Date: Thu, 12 Sep 2019 14:51:51 +1000 +Subject: [PATCH] add guard page(s) between static_tls and stack + +--- + libc/bionic/pthread_create.cpp | 29 +++++++++++++++++++---------- + 1 file changed, 19 insertions(+), 10 deletions(-) + +diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp +index 4cf14ad72b..6bbf970a0b 100644 +--- a/libc/bionic/pthread_create.cpp ++++ b/libc/bionic/pthread_create.cpp +@@ -218,9 +218,10 @@ 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; + +- // Allocate in order: stack guard, stack, static TLS, guard page. ++ // Allocate in order: stack guard, stack, guard page, 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, layout.size(), &mmap_size)) return {}; + if (__builtin_add_overflow(mmap_size, PTHREAD_GUARD_SIZE, &mmap_size)) return {}; + +@@ -229,8 +230,8 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + mmap_size = __BIONIC_ALIGN(mmap_size, PAGE_SIZE); + if (mmap_size < unaligned_size) return {}; + +- // Create a new private anonymous map. Make the entire mapping PROT_NONE, then carve out a +- // read+write area in the middle. ++ // Create a new private anonymous map. Make the entire mapping PROT_NONE, then carve out ++ // read+write areas for the stack and static TLS + const int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE; + char* const space = static_cast(mmap(nullptr, mmap_size, PROT_NONE, flags, -1, 0)); + if (space == MAP_FAILED) { +@@ -240,13 +241,21 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + mmap_size, strerror(errno)); + return {}; + } +- const size_t writable_size = mmap_size - stack_guard_size - PTHREAD_GUARD_SIZE; +- if (mprotect(space + stack_guard_size, +- writable_size, +- PROT_READ | PROT_WRITE) != 0) { ++ ++ if (mprotect(space + stack_guard_size, stack_size, PROT_READ | PROT_WRITE) != 0) { + async_safe_format_log(ANDROID_LOG_WARN, "libc", + "pthread_create failed: couldn't mprotect R+W %zu-byte thread mapping region: %s", +- writable_size, strerror(errno)); ++ stack_size, strerror(errno)); ++ munmap(space, mmap_size); ++ return {}; ++ } ++ ++ char* const static_tls_space = space + stack_guard_size + stack_size + PTHREAD_GUARD_SIZE; ++ ++ if (mprotect(static_tls_space, layout.size(), PROT_READ | PROT_WRITE) != 0) { ++ async_safe_format_log(ANDROID_LOG_WARN, "libc", ++ "pthread_create failed: couldn't mprotect R+W %zu-byte static TLS mapping region: %s", ++ layout.size(), strerror(errno)); + munmap(space, mmap_size); + return {}; + } +@@ -254,9 +263,9 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + ThreadMapping result = {}; + result.mmap_base = space; + result.mmap_size = mmap_size; +- result.static_tls = space + mmap_size - PTHREAD_GUARD_SIZE - layout.size(); ++ result.static_tls = static_tls_space; + result.stack_base = space; +- result.stack_top = result.static_tls; ++ result.stack_top = space + stack_guard_size + stack_size; + return result; + } + diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-16.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-16.patch new file mode 100644 index 00000000..9780dd3d --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-16.patch @@ -0,0 +1,57 @@ +From 5cc8c34e60dbfeb1fd996bf83bb01a0443d93a8a Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Thu, 10 Oct 2019 22:52:49 -0400 +Subject: [PATCH] move pthread_internal_t behind guard page + +--- + libc/bionic/pthread_create.cpp | 19 +++++++++---------- + 1 file changed, 9 insertions(+), 10 deletions(-) + +diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp +index 6bbf970a0b..b4a044db18 100644 +--- a/libc/bionic/pthread_create.cpp ++++ b/libc/bionic/pthread_create.cpp +@@ -218,10 +218,13 @@ 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; + +- // Allocate in order: stack guard, stack, guard page, static TLS, guard page. ++ 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. + 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, 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 {}; + +@@ -250,9 +253,10 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + return {}; + } + +- char* const static_tls_space = space + stack_guard_size + stack_size + PTHREAD_GUARD_SIZE; ++ char* const thread = space + stack_guard_size + stack_size + PTHREAD_GUARD_SIZE; ++ char* const static_tls_space = thread + thread_page_size; + +- if (mprotect(static_tls_space, layout.size(), PROT_READ | PROT_WRITE) != 0) { ++ if (mprotect(thread, thread_page_size + layout.size(), PROT_READ | PROT_WRITE) != 0) { + async_safe_format_log(ANDROID_LOG_WARN, "libc", + "pthread_create failed: couldn't mprotect R+W %zu-byte static TLS mapping region: %s", + layout.size(), strerror(errno)); +@@ -295,13 +299,8 @@ static int __allocate_thread(pthread_attr_t* attr, bionic_tcb** tcbp, void** chi + stack_top = static_cast(attr->stack_base) + attr->stack_size; + } + +- // Carve out space from the stack for the thread's pthread_internal_t. This +- // memory isn't counted in pthread_attr_getstacksize. +- +- // To safely access the pthread_internal_t and thread stack, we need to find a 16-byte aligned boundary. +- stack_top = align_down(stack_top - sizeof(pthread_internal_t), 16); +- +- pthread_internal_t* thread = reinterpret_cast(stack_top); ++ pthread_internal_t* thread = reinterpret_cast( ++ mapping.static_tls - __BIONIC_ALIGN(sizeof(pthread_internal_t), PAGE_SIZE)); + if (!stack_clean) { + // If thread was not allocated by mmap(), it may not have been cleared to zero. + // So assume the worst and zero it. diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-17.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-17.patch new file mode 100644 index 00000000..0bd48939 --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-17.patch @@ -0,0 +1,97 @@ +From 7f61cc8a1c9abd04094a96959f242b7906fa3127 Mon Sep 17 00:00:00 2001 +From: Renlord +Date: Sun, 20 Oct 2019 08:17:11 +1100 +Subject: [PATCH] add secondary stack randomization + +--- + 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 b4a044db18..c2b61a2171 100644 +--- a/libc/bionic/pthread_create.cpp ++++ b/libc/bionic/pthread_create.cpp +@@ -29,6 +29,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -218,12 +219,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 {}; +@@ -245,15 +258,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) { +@@ -269,7 +288,10 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + result.mmap_size = mmap_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(__BIONIC_ALIGN_DOWN(reinterpret_cast(result.stack_top), 16)); + return result; + } + +diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h +index a919a79224..d223f7f871 100644 +--- a/libc/include/sys/cdefs.h ++++ b/libc/include/sys/cdefs.h +@@ -57,6 +57,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. diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-2.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-2.patch new file mode 100644 index 00000000..4ace3853 --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-2.patch @@ -0,0 +1,74 @@ +From b28302c668013a5588a6939f0bbced0b7b288cc2 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 566c33a7a6..ef93055139 100644 +--- a/libc/bionic/brk.cpp ++++ b/libc/bionic/brk.cpp +@@ -29,48 +29,16 @@ + #include + #include + +-#if defined(__LP64__) +-static void* __bionic_brk; +-#else +-void* __bionic_brk; // Accidentally exported by the NDK. ++#if !defined(__LP64__) ++void* __bionic_brk = reinterpret_cast(-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 == nullptr) { +- __bionic_brk = __brk(nullptr); +- } +- +- // 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(__bionic_brk); +- if ((increment > 0 && static_cast(increment) > (UINTPTR_MAX - old_brk)) || +- (increment < 0 && static_cast(-increment) > old_brk)) { +- errno = ENOMEM; +- return reinterpret_cast(-1); +- } +- +- void* desired_brk = reinterpret_cast(old_brk + increment); +- __bionic_brk = __brk(desired_brk); +- if (__bionic_brk < desired_brk) { +- errno = ENOMEM; +- return reinterpret_cast(-1); +- } +- +- return reinterpret_cast(old_brk); ++void* sbrk(ptrdiff_t) { ++ errno = ENOMEM; ++ return reinterpret_cast(-1); + } diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-3.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-3.patch new file mode 100644 index 00000000..7756091c --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-3.patch @@ -0,0 +1,58 @@ +From 9f8be7d07cc063933f8def97672c7671dd4fc360 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 + #include + +-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(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(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; + } diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-4.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-4.patch new file mode 100644 index 00000000..47104c6f --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-4.patch @@ -0,0 +1,25 @@ +From cb91a7ee3aed607dab2d89f2f6b823bf28ea34a0 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 1f5036677a..fc622cbd76 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); diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-5.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-5.patch new file mode 100644 index 00000000..1b3d64d8 --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-5.patch @@ -0,0 +1,46 @@ +From 08279e2fdd75d20ede2a56c326604f426557cea4 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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) { diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-6.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-6.patch new file mode 100644 index 00000000..b6f201e0 --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-6.patch @@ -0,0 +1,39 @@ +From 6a18bd565d9344db5f46f2bb423309dcb134be6e Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 6182ed801c..ccb15a9959 100644 +--- a/libc/bionic/bionic_systrace.cpp ++++ b/libc/bionic/bionic_systrace.cpp +@@ -26,8 +26,6 @@ + + #include // 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() { diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-7.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-7.patch new file mode 100644 index 00000000..1ce828ab --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-7.patch @@ -0,0 +1,25 @@ +From 2f392c2d081fad13f61164ab07841818b972f950 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 e720c046d9..4f7c80e1b9 100644 +--- a/libc/bionic/pthread_internal.h ++++ b/libc/bionic/pthread_internal.h +@@ -218,7 +218,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) diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-8.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-8.patch new file mode 100644 index 00000000..4e9de2e9 --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-8.patch @@ -0,0 +1,58 @@ +From 8bbce1bc50f7b0fb210de3ef160542bbb08cdcc0 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp +index 4984e38a13..2e3967daab 100644 +--- a/libc/bionic/__libc_init_main_thread.cpp ++++ b/libc/bionic/__libc_init_main_thread.cpp +@@ -28,6 +28,9 @@ + + #include "libc_init_common.h" + ++#include ++#include ++ + #include + + #include "private/KernelArgumentBlock.h" +@@ -35,17 +38,20 @@ + #include "private/bionic_defs.h" + #include "private/bionic_elf_tls.h" + #include "private/bionic_globals.h" +-#include "private/bionic_ssp.h" + #include "pthread_internal.h" + + extern "C" pid_t __getpid(); + 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}; + + static pthread_internal_t main_thread; + ++void __libc_init_global_stack_chk_guard(KernelArgumentBlock& args) { ++} ++ + // Setup for the main thread. For dynamic executables, this is called by the + // linker _before_ libc is mapped in memory. This means that all writes to + // globals from this function will apply to linker-private copies and will not +@@ -101,7 +107,10 @@ extern "C" void __libc_init_main_thread_late() { + // The TLS stack guard is set from the global, so ensure that we've initialized the global + // before we initialize the TLS. Dynamic executables will initialize their copy of the global + // stack protector from the one in the main thread's TLS. +- __libc_safe_arc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard)); ++ __libc_safe_arc4random_buf(&__stack_chk_guard[0], sizeof(__stack_chk_guard[0])); ++ if (mprotect(__stack_chk_guard, sizeof(__stack_chk_guard), PROT_READ) == -1) { ++ async_safe_fatal("mprotect __stack_chk_guard: %s", strerror(errno)); ++ } + __init_tcb_stack_guard(__get_bionic_tcb()); + + __init_thread(&main_thread); diff --git a/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-9.patch b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-9.patch new file mode 100644 index 00000000..eb19b310 --- /dev/null +++ b/Patches/LineageOS-17.1/android_bionic/0003-Graphene_Bionic_Hardening-9.patch @@ -0,0 +1,40 @@ +From 725f61db82eb41098291ce06445ccfbf5d5b3581 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp +index 2e3967daab..f5128de9ec 100644 +--- a/libc/bionic/__libc_init_main_thread.cpp ++++ b/libc/bionic/__libc_init_main_thread.cpp +@@ -49,8 +49,11 @@ uintptr_t __stack_chk_guard[PAGE_SIZE / sizeof(uintptr_t)] = {0}; + + static pthread_internal_t main_thread; + +-void __libc_init_global_stack_chk_guard(KernelArgumentBlock& args) { +-} ++#if __LP64__ ++static const uintptr_t canary_mask = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ? ++ 0xffffffffffffff00UL : ++ 0x00ffffffffffffffUL; ++#endif + + // Setup for the main thread. For dynamic executables, this is called by the + // linker _before_ libc is mapped in memory. This means that all writes to +@@ -108,6 +111,10 @@ extern "C" void __libc_init_main_thread_late() { + // before we initialize the TLS. Dynamic executables will initialize their copy of the global + // stack protector from the one in the main thread's TLS. + __libc_safe_arc4random_buf(&__stack_chk_guard[0], sizeof(__stack_chk_guard[0])); ++#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)); + } diff --git a/Patches/LineageOS-17.1/android_system_core/0003-Zero_Sensitive_Info.patch b/Patches/LineageOS-17.1/android_system_core/0003-Zero_Sensitive_Info.patch new file mode 100644 index 00000000..93dd8c10 --- /dev/null +++ b/Patches/LineageOS-17.1/android_system_core/0003-Zero_Sensitive_Info.patch @@ -0,0 +1,21 @@ +From aa9cc05d07a5855fcae2d9f21dd9672543eafbb3 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 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"; + } diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-1.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-1.patch new file mode 100644 index 00000000..d342c5ed --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-1.patch @@ -0,0 +1,85 @@ +From 5412c371955014eee8b2246b386ae7f539bac09e Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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.map.txt | 1 + + libc/upstream-openbsd/android/include/openbsd-compat.h | 2 -- + 5 files changed, 10 insertions(+), 2 deletions(-) + create mode 100644 libc/bionic/explicit_bzero.cpp + +diff --git a/libc/Android.bp b/libc/Android.bp +index d3271ae919..043a03245d 100644 +--- a/libc/Android.bp ++++ b/libc/Android.bp +@@ -1028,6 +1028,7 @@ cc_library_static { + "bionic/error.cpp", + "bionic/eventfd.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 ++ ++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 0cc5611aa8..befffd0828 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.map.txt b/libc/libc.map.txt +index 4bfb8a2320..36803984e9 100644 +--- a/libc/libc.map.txt ++++ b/libc/libc.map.txt +@@ -332,6 +332,7 @@ LIBC { + execvp; + execvpe; # introduced=21 + exit; ++ explicit_bzero; # introduced=30 + faccessat; + 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 878f71cec6..79a2604259 100644 +--- a/libc/upstream-openbsd/android/include/openbsd-compat.h ++++ b/libc/upstream-openbsd/android/include/openbsd-compat.h +@@ -53,8 +53,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 , but "ALIGN" isn't something we want to reserve. */ + #define ALIGNBYTES (sizeof(uintptr_t) - 1) + #define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES) diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-10.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-10.patch new file mode 100644 index 00000000..973daf7c --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-10.patch @@ -0,0 +1,84 @@ +From 2e613ccbe7a6b2aa8f1688ed8493267d12c66d23 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Wed, 2 Dec 2015 23:37:28 -0500 +Subject: [PATCH] switch pthread_atfork handler allocation to mmap + +Signed-off-by: anupritaisno1 +--- + 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 0dcabdfb2d..6306052ee3 100644 +--- a/libc/bionic/pthread_atfork.cpp ++++ b/libc/bionic/pthread_atfork.cpp +@@ -29,6 +29,9 @@ + #include + #include + #include ++#include ++#include ++#include + + #include "platform/bionic/macros.h" + +@@ -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(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(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(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); diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-11.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-11.patch new file mode 100644 index 00000000..05afaec0 --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-11.patch @@ -0,0 +1,95 @@ +From e239c7dff88bbc37a3e902a695565fdbf6ed0b08 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Thu, 3 Dec 2015 12:58:31 -0500 +Subject: [PATCH] add memory protection for pthread_atfork handlers + +Signed-off-by: anupritaisno1 +--- + 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 6306052ee3..d59f3ae54b 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(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(it); + node->next = pool; + pool = node; + } ++ ++ atfork_t* page_node = reinterpret_cast(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,8 +216,20 @@ 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); + } diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-12.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-12.patch new file mode 100644 index 00000000..a57ec15a --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-12.patch @@ -0,0 +1,85 @@ +From 0b03d92b7f2dc5f12211037e99821ccead27a687 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Wed, 27 Jan 2016 18:02:15 -0500 +Subject: [PATCH] add XOR mangling mitigation for thread-local dtors + +Signed-off-by: anupritaisno1 +--- + 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 + #include + + #include ++#include + + #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(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(__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 a82ca50b69..2ad0b58c5a 100644 +--- a/libc/bionic/libc_init_common.cpp ++++ b/libc/bionic/libc_init_common.cpp +@@ -45,6 +45,7 @@ + #include + + #include "private/WriteProtected.h" ++#include "private/bionic_arc4random.h" + #include "private/bionic_defs.h" + #include "private/bionic_globals.h" + #include "private/bionic_tls.h" +@@ -66,6 +67,7 @@ void __libc_init_globals() { + __libc_globals.mutate([](libc_globals* globals) { + __libc_init_vdso(globals); + __libc_init_setjmp_cookie(globals); ++ arc4random_buf(&globals->dtor_cookie, sizeof(globals->dtor_cookie)); + }); + } + +diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h +index 6e7eb76e40..1b75ca0ee6 100644 +--- a/libc/private/bionic_globals.h ++++ b/libc/private/bionic_globals.h +@@ -43,6 +43,7 @@ + + struct libc_globals { + vdso_entry vdso[VDSO_END]; ++ long dtor_cookie; + long setjmp_cookie; + uintptr_t heap_pointer_tag; + diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-13.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-13.patch new file mode 100644 index 00000000..2354174b --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-13.patch @@ -0,0 +1,25 @@ +From de08419b8256ab7daf6ef7c7835348f9aaeb7478 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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. + +Signed-off-by: anupritaisno1 +--- + 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 3c4b169eed..a27201706e 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; + } + diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-14.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-14.patch new file mode 100644 index 00000000..b211f7e8 --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-14.patch @@ -0,0 +1,76 @@ +From 897d4903e24c9f6b772539e9f8e0bf3520ed8838 Mon Sep 17 00:00:00 2001 +From: Renlord +Date: Thu, 12 Sep 2019 14:51:51 +1000 +Subject: [PATCH] add guard page(s) between static_tls and stack + +Signed-off-by: anupritaisno1 +--- + libc/bionic/pthread_create.cpp | 29 +++++++++++++++++++---------- + 1 file changed, 19 insertions(+), 10 deletions(-) + +diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp +index d4a8bef269..eac53cac85 100644 +--- a/libc/bionic/pthread_create.cpp ++++ b/libc/bionic/pthread_create.cpp +@@ -199,9 +199,10 @@ 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; + +- // Allocate in order: stack guard, stack, static TLS, guard page. ++ // Allocate in order: stack guard, stack, guard page, 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, layout.size(), &mmap_size)) return {}; + if (__builtin_add_overflow(mmap_size, PTHREAD_GUARD_SIZE, &mmap_size)) return {}; + +@@ -210,8 +211,8 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + mmap_size = __BIONIC_ALIGN(mmap_size, PAGE_SIZE); + if (mmap_size < unaligned_size) return {}; + +- // Create a new private anonymous map. Make the entire mapping PROT_NONE, then carve out a +- // read+write area in the middle. ++ // Create a new private anonymous map. Make the entire mapping PROT_NONE, then carve out ++ // read+write areas for the stack and static TLS + const int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE; + char* const space = static_cast(mmap(nullptr, mmap_size, PROT_NONE, flags, -1, 0)); + if (space == MAP_FAILED) { +@@ -221,13 +222,21 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + mmap_size, strerror(errno)); + return {}; + } +- const size_t writable_size = mmap_size - stack_guard_size - PTHREAD_GUARD_SIZE; +- if (mprotect(space + stack_guard_size, +- writable_size, +- PROT_READ | PROT_WRITE) != 0) { ++ ++ if (mprotect(space + stack_guard_size, stack_size, PROT_READ | PROT_WRITE) != 0) { + async_safe_format_log(ANDROID_LOG_WARN, "libc", + "pthread_create failed: couldn't mprotect R+W %zu-byte thread mapping region: %s", +- writable_size, strerror(errno)); ++ stack_size, strerror(errno)); ++ munmap(space, mmap_size); ++ return {}; ++ } ++ ++ char* const static_tls_space = space + stack_guard_size + stack_size + PTHREAD_GUARD_SIZE; ++ ++ if (mprotect(static_tls_space, layout.size(), PROT_READ | PROT_WRITE) != 0) { ++ async_safe_format_log(ANDROID_LOG_WARN, "libc", ++ "pthread_create failed: couldn't mprotect R+W %zu-byte static TLS mapping region: %s", ++ layout.size(), strerror(errno)); + munmap(space, mmap_size); + return {}; + } +@@ -237,9 +246,9 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + result.mmap_size = mmap_size; + result.mmap_base_unguarded = space + stack_guard_size; + result.mmap_size_unguarded = mmap_size - stack_guard_size - PTHREAD_GUARD_SIZE; +- result.static_tls = space + mmap_size - PTHREAD_GUARD_SIZE - layout.size(); ++ result.static_tls = static_tls_space; + result.stack_base = space; +- result.stack_top = result.static_tls; ++ result.stack_top = space + stack_guard_size + stack_size; + return result; + } + diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-15.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-15.patch new file mode 100644 index 00000000..2ce9e8f6 --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-15.patch @@ -0,0 +1,58 @@ +From 648cd68ca3ffefe685ae6acdae17171c8acfa75b Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Thu, 10 Oct 2019 22:52:49 -0400 +Subject: [PATCH] move pthread_internal_t behind guard page + +Signed-off-by: anupritaisno1 +--- + libc/bionic/pthread_create.cpp | 19 +++++++++---------- + 1 file changed, 9 insertions(+), 10 deletions(-) + +diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp +index eac53cac85..336e69b597 100644 +--- a/libc/bionic/pthread_create.cpp ++++ b/libc/bionic/pthread_create.cpp +@@ -199,10 +199,13 @@ 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; + +- // Allocate in order: stack guard, stack, guard page, static TLS, guard page. ++ 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. + 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, 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 {}; + +@@ -231,9 +234,10 @@ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_si + return {}; + } + +- char* const static_tls_space = space + stack_guard_size + stack_size + PTHREAD_GUARD_SIZE; ++ char* const thread = space + stack_guard_size + stack_size + PTHREAD_GUARD_SIZE; ++ char* const static_tls_space = thread + thread_page_size; + +- if (mprotect(static_tls_space, layout.size(), PROT_READ | PROT_WRITE) != 0) { ++ if (mprotect(thread, thread_page_size + layout.size(), PROT_READ | PROT_WRITE) != 0) { + async_safe_format_log(ANDROID_LOG_WARN, "libc", + "pthread_create failed: couldn't mprotect R+W %zu-byte static TLS mapping region: %s", + layout.size(), strerror(errno)); +@@ -278,13 +282,8 @@ static int __allocate_thread(pthread_attr_t* attr, bionic_tcb** tcbp, void** chi + stack_top = static_cast(attr->stack_base) + attr->stack_size; + } + +- // Carve out space from the stack for the thread's pthread_internal_t. This +- // memory isn't counted in pthread_attr_getstacksize. +- +- // To safely access the pthread_internal_t and thread stack, we need to find a 16-byte aligned boundary. +- stack_top = align_down(stack_top - sizeof(pthread_internal_t), 16); +- +- pthread_internal_t* thread = reinterpret_cast(stack_top); ++ pthread_internal_t* thread = reinterpret_cast( ++ mapping.static_tls - __BIONIC_ALIGN(sizeof(pthread_internal_t), PAGE_SIZE)); + if (!stack_clean) { + // If thread was not allocated by mmap(), it may not have been cleared to zero. + // So assume the worst and zero it. diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-16.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-16.patch new file mode 100644 index 00000000..e7dca761 --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-16.patch @@ -0,0 +1,98 @@ +From 0bc4dbcbd27c7f48713913101fb3c868c215c1a3 Mon Sep 17 00:00:00 2001 +From: Renlord +Date: Sun, 20 Oct 2019 08:17:11 +1100 +Subject: [PATCH] add secondary stack randomization + +Signed-off-by: anupritaisno1 +--- + 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 + + #include ++#include + #include + #include + #include +@@ -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(__BIONIC_ALIGN_DOWN(reinterpret_cast(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. diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-2.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-2.patch new file mode 100644 index 00000000..ae5bb2ad --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-2.patch @@ -0,0 +1,76 @@ +From 31456ac632903235e14500af8b5d7dff2d25d724 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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. + +Signed-off-by: anupritaisno1 +--- + 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 566c33a7a6..ef93055139 100644 +--- a/libc/bionic/brk.cpp ++++ b/libc/bionic/brk.cpp +@@ -29,48 +29,16 @@ + #include + #include + +-#if defined(__LP64__) +-static void* __bionic_brk; +-#else +-void* __bionic_brk; // Accidentally exported by the NDK. ++#if !defined(__LP64__) ++void* __bionic_brk = reinterpret_cast(-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 == nullptr) { +- __bionic_brk = __brk(nullptr); +- } +- +- // 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(__bionic_brk); +- if ((increment > 0 && static_cast(increment) > (UINTPTR_MAX - old_brk)) || +- (increment < 0 && static_cast(-increment) > old_brk)) { +- errno = ENOMEM; +- return reinterpret_cast(-1); +- } +- +- void* desired_brk = reinterpret_cast(old_brk + increment); +- __bionic_brk = __brk(desired_brk); +- if (__bionic_brk < desired_brk) { +- errno = ENOMEM; +- return reinterpret_cast(-1); +- } +- +- return reinterpret_cast(old_brk); ++void* sbrk(ptrdiff_t) { ++ errno = ENOMEM; ++ return reinterpret_cast(-1); + } diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-3.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-3.patch new file mode 100644 index 00000000..42e5f3c6 --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-3.patch @@ -0,0 +1,55 @@ +From 58ebc243ea3085056e6aba765d879807fa1a46d6 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Mon, 4 Mar 2019 04:26:04 -0500 +Subject: [PATCH] use blocking getrandom and avoid urandom fallback + +Signed-off-by: anupritaisno1 +--- + libc/bionic/getentropy.cpp | 26 ++------------------------ + 1 file changed, 2 insertions(+), 24 deletions(-) + +diff --git a/libc/bionic/getentropy.cpp b/libc/bionic/getentropy.cpp +index 9c93e713b7..9b40852675 100644 +--- a/libc/bionic/getentropy.cpp ++++ b/libc/bionic/getentropy.cpp +@@ -33,22 +33,6 @@ + + #include "private/ScopedFd.h" + +-static int getentropy_urandom(void* buffer, size_t buffer_size, int saved_errno) { +- ScopedFd fd(TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY | O_NOFOLLOW | O_CLOEXEC, 0))); +- if (fd.get() == -1) return -1; +- +- size_t collected = 0; +- while (collected < buffer_size) { +- ssize_t count = TEMP_FAILURE_RETRY(read(fd.get(), static_cast(buffer) + collected, +- buffer_size - collected)); +- if (count == -1) return -1; +- collected += count; +- } +- +- errno = saved_errno; +- return 0; +-} +- + int getentropy(void* buffer, size_t buffer_size) { + if (buffer_size > 256) { + errno = EIO; +@@ -60,15 +44,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(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; + } diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-4.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-4.patch new file mode 100644 index 00000000..1e801aae --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-4.patch @@ -0,0 +1,26 @@ +From 5323b39f7ec1fce2d788f1c8a2c28cfd32d5ccc4 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Mon, 19 Sep 2016 07:57:43 -0400 +Subject: [PATCH] fix undefined out-of-bounds accesses in sched.h + +Signed-off-by: anupritaisno1 +--- + 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 3260231cf0..00c2a4a452 100644 +--- a/libc/include/sched.h ++++ b/libc/include/sched.h +@@ -70,7 +70,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); diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-5.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-5.patch new file mode 100644 index 00000000..d4063736 --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-5.patch @@ -0,0 +1,47 @@ +From 6a91d9dddb01964134e50cc73f6f158706da800a Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Sat, 19 Nov 2016 09:56:14 -0500 +Subject: [PATCH] stop implicitly marking mappings as mergeable + +Signed-off-by: anupritaisno1 +--- + 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 9aad0b3156..6bf0ecfd16 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) { diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-6.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-6.patch new file mode 100644 index 00000000..357580a2 --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-6.patch @@ -0,0 +1,40 @@ +From a042b5a0bada9933b7c488003e8f9d8d0d195525 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Sat, 16 Jul 2016 23:55:16 -0400 +Subject: [PATCH] replace VLA formatting with dprintf-like function + +Signed-off-by: anupritaisno1 +--- + 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 fd97712982..acd9b76814 100644 +--- a/libc/bionic/bionic_systrace.cpp ++++ b/libc/bionic/bionic_systrace.cpp +@@ -27,8 +27,6 @@ + #include + #include // 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; +@@ -65,15 +63,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 = async_safe_format_buffer(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)); ++ async_safe_format_fd(trace_marker_fd, "B|%d|%s", getpid(), message); + } + + void bionic_trace_end() { diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-7.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-7.patch new file mode 100644 index 00000000..3d83da2a --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-7.patch @@ -0,0 +1,26 @@ +From 9ec639de1bec2f655bdfc0750e363a6f8de31c4a Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Fri, 17 Jul 2015 21:32:05 -0400 +Subject: [PATCH] increase default pthread stack to 8MiB on 64-bit + +Signed-off-by: anupritaisno1 +--- + 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 d58725baf1..a108f5cc0d 100644 +--- a/libc/bionic/pthread_internal.h ++++ b/libc/bionic/pthread_internal.h +@@ -234,7 +234,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) diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-8.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-8.patch new file mode 100644 index 00000000..e8777657 --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-8.patch @@ -0,0 +1,59 @@ +From 49571a0a496539b9af763b8ef30c5b5db57c8be7 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +Date: Sat, 1 Oct 2016 05:11:44 -0400 +Subject: [PATCH] make __stack_chk_guard read-only at runtime + +Signed-off-by: anupritaisno1 +--- + libc/bionic/__libc_init_main_thread.cpp | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp +index 56a8488888..7c8256cd67 100644 +--- a/libc/bionic/__libc_init_main_thread.cpp ++++ b/libc/bionic/__libc_init_main_thread.cpp +@@ -28,6 +28,9 @@ + + #include "libc_init_common.h" + ++#include ++#include ++ + #include + + #include "private/KernelArgumentBlock.h" +@@ -35,17 +38,20 @@ + #include "private/bionic_defs.h" + #include "private/bionic_elf_tls.h" + #include "private/bionic_globals.h" +-#include "private/bionic_ssp.h" + #include "pthread_internal.h" + + extern "C" pid_t __getpid(); + 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}; + + static pthread_internal_t main_thread; + ++void __libc_init_global_stack_chk_guard(KernelArgumentBlock& args) { ++} ++ + // Setup for the main thread. For dynamic executables, this is called by the + // linker _before_ libc is mapped in memory. This means that all writes to + // globals from this function will apply to linker-private copies and will not +@@ -122,7 +128,10 @@ extern "C" void __libc_init_main_thread_late() { + // The TLS stack guard is set from the global, so ensure that we've initialized the global + // before we initialize the TLS. Dynamic executables will initialize their copy of the global + // stack protector from the one in the main thread's TLS. +- __libc_safe_arc4random_buf(&__stack_chk_guard, sizeof(__stack_chk_guard)); ++ __libc_safe_arc4random_buf(&__stack_chk_guard[0], sizeof(__stack_chk_guard[0])); ++ if (mprotect(__stack_chk_guard, sizeof(__stack_chk_guard), PROT_READ) == -1) { ++ async_safe_fatal("mprotect __stack_chk_guard: %s", strerror(errno)); ++ } + __init_tcb_stack_guard(__get_bionic_tcb()); + + __init_thread(&main_thread); diff --git a/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-9.patch b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-9.patch new file mode 100644 index 00000000..2c75aa8a --- /dev/null +++ b/Patches/LineageOS-18.1/android_bionic/0002-Graphene_Bionic_Hardening-9.patch @@ -0,0 +1,42 @@ +From 149cc5ccb870640b2536b6bd5dfa1292f9dd6178 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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. + +Signed-off-by: anupritaisno1 +--- + libc/bionic/__libc_init_main_thread.cpp | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp +index 7c8256cd67..554477674a 100644 +--- a/libc/bionic/__libc_init_main_thread.cpp ++++ b/libc/bionic/__libc_init_main_thread.cpp +@@ -49,8 +49,11 @@ uintptr_t __stack_chk_guard[PAGE_SIZE / sizeof(uintptr_t)] = {0}; + + static pthread_internal_t main_thread; + +-void __libc_init_global_stack_chk_guard(KernelArgumentBlock& args) { +-} ++#if __LP64__ ++static const uintptr_t canary_mask = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ? ++ 0xffffffffffffff00UL : ++ 0x00ffffffffffffffUL; ++#endif + + // Setup for the main thread. For dynamic executables, this is called by the + // linker _before_ libc is mapped in memory. This means that all writes to +@@ -129,6 +132,10 @@ extern "C" void __libc_init_main_thread_late() { + // before we initialize the TLS. Dynamic executables will initialize their copy of the global + // stack protector from the one in the main thread's TLS. + __libc_safe_arc4random_buf(&__stack_chk_guard[0], sizeof(__stack_chk_guard[0])); ++#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)); + } diff --git a/Patches/LineageOS-18.1/android_system_core/0004-Zero_Sensitive_Info.patch b/Patches/LineageOS-18.1/android_system_core/0004-Zero_Sensitive_Info.patch new file mode 100644 index 00000000..7caac40a --- /dev/null +++ b/Patches/LineageOS-18.1/android_system_core/0004-Zero_Sensitive_Info.patch @@ -0,0 +1,21 @@ +From b3a0c2c5db28852b6d485542c8a4f1649a256892 Mon Sep 17 00:00:00 2001 +From: Daniel Micay +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 6cbe642c081..82fc8ca6413 100644 +--- a/init/security.cpp ++++ b/init/security.cpp +@@ -78,6 +78,7 @@ Result 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"; + } diff --git a/Scripts/LineageOS-16.0/Patch.sh b/Scripts/LineageOS-16.0/Patch.sh index b956952f..32173241 100644 --- a/Scripts/LineageOS-16.0/Patch.sh +++ b/Scripts/LineageOS-16.0/Patch.sh @@ -61,6 +61,23 @@ fi; if enterAndClear "bionic"; then if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_bionic/0001-HM-Use_HM.patch"; fi; #(GrapheneOS) +if [ "$DOS_GRAPHENE_BIONIC" = true ]; then +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-1.patch"; #Add a real explicit_bzero implementation #(GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-2.patch"; #Replace brk and sbrk with stubs #(GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-3.patch"; #Use blocking getrandom and avoid urandom fallback #(GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-4.patch"; #Fix undefined out-of-bounds accesses in sched.h #(GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-5.patch"; #Stop implicitly marking mappings as mergeable #(GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-6.patch"; #Replace VLA formatting buffer with dprintf #(GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-7.patch"; #Increase default pthread stack to 8MiB on 64-bit #(GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-8.patch"; #Make __stack_chk_guard read-only at runtime #(GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-9.patch"; #On 64-bit, zero the leading stack canary byte #(GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-10.patch"; #Switch pthread_atfork handler allocation to mmap #(GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-11.patch"; #Add memory protection for pthread_atfork handlers #(GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-12.patch"; #Add memory protection for at_quick_exit #(GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-13.patch"; #Add XOR mangling mitigation for thread-local dtors #(GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-14.patch"; #Use a better pthread_attr junk filling pattern #(GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-15.patch"; #Move pthread_internal_t out of the stack mapping #(GrapheneOS) +fi; fi; if enterAndClear "bootable/recovery"; then @@ -302,6 +319,7 @@ if [ "$DOS_HOSTS_BLOCKING" = true ]; then cat "$DOS_HOSTS_FILE" >> rootdir/etc/h git revert --no-edit b3609d82999d23634c5e6db706a3ecbc5348309a; #Always update recovery applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts with nodev/noexec/nosuid + misc sysctl changes (GrapheneOS) if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0002-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS) +if [ "$DOS_GRAPHENE_BIONIC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-Zero_Sensitive_Info.patch"; fi; #Zero sensitive information with explicit_bzero (GrapheneOS) fi; if enterAndClear "system/extras"; then diff --git a/Scripts/LineageOS-17.1/Patch.sh b/Scripts/LineageOS-17.1/Patch.sh index 76085f33..acf24c6b 100644 --- a/Scripts/LineageOS-17.1/Patch.sh +++ b/Scripts/LineageOS-17.1/Patch.sh @@ -66,6 +66,25 @@ fi; if enterAndClear "bionic"; then if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_bionic/0001-HM-Use_HM.patch"; fi; #(GrapheneOS) if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_bionic/0002-Symbol_Ordering.patch"; fi; #(GrapheneOS) +if [ "$DOS_GRAPHENE_BIONIC" = true ]; then +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-1.patch"; #Add a real explicit_bzero implementation (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-2.patch"; #Replace brk and sbrk with stubs (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-3.patch"; #Use blocking getrandom and avoid urandom fallback (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-4.patch"; #Fix undefined out-of-bounds accesses in sched.h (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-5.patch"; #Stop implicitly marking mappings as mergeable (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-6.patch"; #Replace VLA formatting buffer with dprintf (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-7.patch"; #Increase default pthread stack to 8MiB on 64-bit (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-8.patch"; #Make __stack_chk_guard read-only at runtime (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-9.patch"; #On 64-bit, zero the leading stack canary byte (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-10.patch"; #Switch pthread_atfork handler allocation to mmap (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-11.patch"; #Add memory protection for pthread_atfork handlers (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-12.patch"; #Add memory protection for at_quick_exit (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-13.patch"; #Add XOR mangling mitigation for thread-local dtors (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-14.patch"; #Use a better pthread_attr junk filling pattern (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-15.patch"; #Add guard page(s) between static_tls and stack (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-16.patch"; #Move pthread_internal_t behind guard page (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0003-Graphene_Bionic_Hardening-17.patch"; #Add secondary stack randomization (GrapheneOS) +fi; fi; if enterAndClear "build/make"; then @@ -308,6 +327,7 @@ git revert --no-edit 3032c7aa5ce90c0ae9c08fe271052c6e0304a1e7 01266f589e6deaef30 git revert --no-edit bd4142eab8b3cead0c25a2e660b4b048d1315d3c; #Always update recovery applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts with nodev/noexec/nosuid + misc sysctl changes (GrapheneOS) if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0002-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS) +if [ "$DOS_GRAPHENE_BIONIC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-Zero_Sensitive_Info.patch"; fi; #Zero sensitive information with explicit_bzero (GrapheneOS) fi; if enterAndClear "system/extras"; then diff --git a/Scripts/LineageOS-18.1/Patch.sh b/Scripts/LineageOS-18.1/Patch.sh index 5ba58058..df4c26e2 100644 --- a/Scripts/LineageOS-18.1/Patch.sh +++ b/Scripts/LineageOS-18.1/Patch.sh @@ -59,9 +59,27 @@ if enterAndClear "art"; then if [ "$DOS_GRAPHENE_CONSTIFY" = true ]; then applyPatch "$DOS_PATCHES/android_art/0001-constify_JNINativeMethod.patch"; fi; #Constify JNINativeMethod tables (GrapheneOS) fi; -#if enterAndClear "bionic"; then +if enterAndClear "bionic"; then #if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_bionic/0001-HM-Use_HM.patch"; fi; #(GrapheneOS) #XXX: needs to be verified -#fi; +if [ "$DOS_GRAPHENE_BIONIC" = true ]; then +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-1.patch"; #Add a real explicit_bzero implementation (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-2.patch"; #Replace brk and sbrk with stubs (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-3.patch"; #Use blocking getrandom and avoid urandom fallback (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-4.patch"; #Fix undefined out-of-bounds accesses in sched.h (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-5.patch"; #Stop implicitly marking mappings as mergeable (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-6.patch"; #Replace VLA formatting with dprintf-like function (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-7.patch"; #Increase default pthread stack to 8MiB on 64-bit (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-8.patch"; #Make __stack_chk_guard read-only at runtime (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-9.patch"; #On 64-bit, zero the leading stack canary byte (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-10.patch"; #Switch pthread_atfork handler allocation to mmap (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-11.patch"; #Add memory protection for pthread_atfork handlers (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-12.patch"; #Add XOR mangling mitigation for thread-local dtors (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-13.patch"; #Use a better pthread_attr junk filling pattern (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-14.patch"; #Add guard page(s) between static_tls and stack (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-15.patch"; #Move pthread_internal_t behind guard page (GrapheneOS) +applyPatch "$DOS_PATCHES/android_bionic/0002-Graphene_Bionic_Hardening-16.patch"; #Add secondary stack randomization (GrapheneOS) +fi; +fi; if enterAndClear "bootable/recovery"; then applyPatch "$DOS_PATCHES/android_bootable_recovery/0001-No_SerialNum_Restrictions.patch"; #Abort package installs if they are specific to a serial number (GrapheneOS) @@ -323,6 +341,7 @@ git revert --no-edit e8dcabaf6b55ec55eb73c4585501ddbafc04fc9b 79f606ece6b74652d3 applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts with nodev/noexec/nosuid + misc sysctl changes (GrapheneOS) if [ "$DOS_GRAPHENE_PTRACE_SCOPE" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0002-ptrace_scope.patch"; fi; #Add a property for controlling ptrace_scope (GrapheneOS) #if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0003-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS) +if [ "$DOS_GRAPHENE_BIONIC" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0004-Zero_Sensitive_Info.patch"; fi; #Zero sensitive information with explicit_bzero (GrapheneOS) fi; if enterAndClear "system/extras"; then diff --git a/Scripts/init.sh b/Scripts/init.sh index 2aeeca6b..d87bc3af 100644 --- a/Scripts/init.sh +++ b/Scripts/init.sh @@ -57,6 +57,7 @@ export DOS_DEBLOBBER_REPLACE_TIME=false; #Set true to replace Qualcomm Time Serv #Features export DOS_GPS_GLONASS_FORCED=false; #Enables GLONASS on all devices +export DOS_GRAPHENE_BIONIC=true; #Enables the bionic hardening patchset on 16.0+17.1+18.1 export DOS_GRAPHENE_CONSTIFY=true; #Enables 'Constify JNINativeMethod tables' patchset on 16.0+17.1+18.1 export DOS_GRAPHENE_MALLOC=true; #Enables use of GrapheneOS' hardened memory allocator on 64-bit platforms on 16.0+17.1+18.1 export DOS_GRAPHENE_EXEC=false; #Enables use of GrapheneOS' exec spawning feature on 16.0+17.1+18.1 XXX: broken (just on 17.1?)