14.1: work on integrating hardened_malloc

untested as all currently supported 14.1 devices are 32-bit

Signed-off-by: Tavi <tavi@divested.dev>
This commit is contained in:
Tavi 2024-05-09 13:25:09 -04:00
parent 31a147ab98
commit 0c88720caa
No known key found for this signature in database
GPG Key ID: E599F62ECBAEAF2E
9 changed files with 1095 additions and 4 deletions

View File

@ -62,9 +62,7 @@
<remove-project name="platform/prebuilts/qemu-kernel" />
<!-- END OF UNNECESSARY REPO REMOVAL -->
<!-- START OF ADDITIONAL REPOS -->
<!--<project path="external/swiftshader" name="google/swiftshader" remote="github" revision="master" />-->
<!-- START OF BRANCH SWITCHING -->
<!-- Switch to the Mulch WebView -->
<remove-project name="LineageOS/android_external_chromium-webview" />
<project path="external/chromium-webview" name="divested-mobile/mulch" groups="pdk" clone-depth="1" remote="gitlab" revision="m119" />
@ -84,6 +82,13 @@
<project path="external/ffmpeg" name="syphyr/android_external_ffmpeg" remote="github" revision="61190001372364379b095b4cd1de6787213def0e" />
<remove-project name="LineageOS/android_external_flac" />
<project path="external/flac" name="syphyr/android_external_flac" remote="github" revision="3c73deb884acf79764a769cac47a12d214929fa5" />
<!-- END OF BRANCH SWITCHING -->
<!-- START OF ADDITIONAL REPOS -->
<!--<project path="external/swiftshader" name="google/swiftshader" remote="github" revision="master" />-->
<!-- GrapheneOS -->
<project path="external/hardened_malloc" name="GrapheneOS/hardened_malloc" remote="github" revision="749640c274d54e084505a24fa758bcb5f96a25ef" />
<!-- END OF ADDITIONAL REPOS -->
<!-- START OF DEVICE REPOS -->

View File

@ -0,0 +1,120 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Micay <danielmicay@gmail.com>
Date: Wed, 5 Dec 2018 01:51:56 -0500
Subject: [PATCH] add hardened_malloc library
---
libc/Android.bp | 45 ++++++++++++++++++++++++++++-------
libc/bionic/malloc_common.cpp | 5 ++++
2 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/libc/Android.bp b/libc/Android.bp
index c92acf70b..7edf0c74f 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -83,6 +83,8 @@ cc_defaults {
"-Werror=int-to-pointer-cast",
"-Werror=type-limits",
"-Werror",
+
+ "-DH_MALLOC_PREFIX",
],
// TODO: split out the asflags.
asflags: [
@@ -99,7 +101,15 @@ cc_defaults {
],
conlyflags: ["-std=gnu99"],
cppflags: [],
- include_dirs: ["external/jemalloc/include"],
+
+ multilib: {
+ lib32: {
+ include_dirs: ["external/jemalloc/include"],
+ },
+ lib64: {
+ include_dirs: ["external/hardened_malloc/"],
+ },
+ },
arch: {
// Clang/llvm has incompatible long double (fp128) for x86_64.
@@ -1601,11 +1611,6 @@ cc_library_static {
name: "libc_ndk",
defaults: ["libc_defaults"],
srcs: libc_common_src_files + ["bionic/malloc_common.cpp"],
- multilib: {
- lib32: {
- srcs: libc_common_src_files_32,
- },
- },
arch: {
arm: {
srcs: [
@@ -1635,8 +1640,17 @@ cc_library_static {
"libc_syscalls",
"libc_tzcode",
"libm",
- "libjemalloc",
],
+
+ multilib: {
+ lib32: {
+ srcs: libc_common_src_files_32,
+ whole_static_libs: ["libjemalloc"],
+ },
+ lib64: {
+ whole_static_libs: ["libhardened_malloc"],
+ },
+ },
}
// ========================================================
@@ -1714,7 +1728,11 @@ cc_library_static {
// ========================================================
cc_library_static {
defaults: ["libc_defaults"],
- srcs: ["bionic/jemalloc_wrapper.cpp"],
+ multilib: {
+ lib32: {
+ srcs: ["bionic/jemalloc_wrapper.cpp"],
+ },
+ },
cflags: ["-fvisibility=hidden"],
name: "libc_malloc",
@@ -1765,7 +1783,16 @@ cc_library {
// you wanted!
shared_libs: ["libdl"],
- whole_static_libs: ["libc_common", "libjemalloc"],
+ whole_static_libs: ["libc_common"],
+
+ multilib: {
+ lib32: {
+ whole_static_libs: ["libjemalloc"],
+ },
+ lib64: {
+ whole_static_libs: ["libhardened_malloc"],
+ },
+ },
// We'd really like to do this for all architectures, but since this wasn't done
// before, these symbols must continue to be exported on LP32 for binary
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index e05061917..af544f3e1 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -46,8 +46,13 @@
#include <private/bionic_globals.h>
#include <private/bionic_malloc_dispatch.h>
+#ifdef __LP64__
+#include "h_malloc.h"
+#define Malloc(function) h_ ## function
+#else
#include "jemalloc.h"
#define Malloc(function) je_ ## function
+#endif
static constexpr MallocDispatch __libc_malloc_default_dispatch
__attribute__((unused)) = {

View File

@ -0,0 +1,310 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christopher Ferris <cferris@google.com>
Date: Mon, 15 May 2017 15:50:19 -0700
Subject: [PATCH] Add support for modifying decay timer.
Add the mallopt function, and only a single option so far.
Bug: 36401135
Test: Built and booted bullhead.
Test: Ran jemalloc unit tests.
Test: Ran bionic unit tests.
Test: Ran a test that allocated and free'd a large piece of memory,
Test: and verified that after changing the parameter, the PSS
Test: sticks around (decay timer set to 1), the PSS is purged (decay
Test: timer set to 0).
Change-Id: I6927929b0c539c1023d34772d9e26bb6a8a45877
---
libc/bionic/jemalloc.h | 1 +
libc/bionic/jemalloc_wrapper.cpp | 36 +++++++++++++++++++
libc/bionic/malloc_common.cpp | 13 +++++++
libc/include/malloc.h | 5 +++
libc/libc.arm.map | 1 +
libc/libc.arm64.map | 1 +
libc/libc.mips.map | 1 +
libc/libc.mips64.map | 1 +
libc/libc.x86.map | 1 +
libc/libc.x86_64.map | 1 +
libc/malloc_debug/malloc_debug.cpp | 5 +++
.../tests/malloc_debug_unit_tests.cpp | 16 +++++++++
libc/private/bionic_malloc_dispatch.h | 2 ++
tests/malloc_test.cpp | 7 ++++
14 files changed, 91 insertions(+)
diff --git a/libc/bionic/jemalloc.h b/libc/bionic/jemalloc.h
index fceb323d3..f7e877056 100644
--- a/libc/bionic/jemalloc.h
+++ b/libc/bionic/jemalloc.h
@@ -26,6 +26,7 @@
__BEGIN_DECLS
struct mallinfo je_mallinfo();
+int je_mallopt(int, int);
int je_iterate(uintptr_t, size_t, void (*)(uintptr_t, size_t, void*), void*);
void je_malloc_disable();
void je_malloc_enable();
diff --git a/libc/bionic/jemalloc_wrapper.cpp b/libc/bionic/jemalloc_wrapper.cpp
index e33d560a4..266b9660c 100644
--- a/libc/bionic/jemalloc_wrapper.cpp
+++ b/libc/bionic/jemalloc_wrapper.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <malloc.h>
#include <sys/param.h>
#include <unistd.h>
@@ -46,3 +47,38 @@ void* je_memalign_round_up_boundary(size_t boundary, size_t size) {
}
return je_memalign(boundary, size);
}
+
+int je_mallopt(int param, int value) {
+ // The only parameter we currently understand is M_DECAY_TIME.
+ if (param == M_DECAY_TIME) {
+ // Only support setting the value to 1 or 0.
+ ssize_t decay_time;
+ if (value) {
+ decay_time = 1;
+ } else {
+ decay_time = 0;
+ }
+ // First get the total number of arenas.
+ unsigned narenas;
+ size_t sz = sizeof(unsigned);
+ if (je_mallctl("arenas.narenas", &narenas, &sz, nullptr, 0) != 0) {
+ return 0;
+ }
+
+ // Set the decay time for any arenas that will be created in the future.
+ if (je_mallctl("arenas.decay_time", nullptr, nullptr, &decay_time, sizeof(decay_time)) != 0) {
+ return 0;
+ }
+
+ // Change the decay on the already existing arenas.
+ char buffer[100];
+ for (unsigned i = 0; i < narenas; i++) {
+ snprintf(buffer, sizeof(buffer), "arena.%d.decay_time", i);
+ if (je_mallctl(buffer, nullptr, nullptr, &decay_time, sizeof(decay_time)) != 0) {
+ break;
+ }
+ }
+ return 1;
+ }
+ return 0;
+}
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index af544f3e1..4257412a3 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -73,6 +73,7 @@ static constexpr MallocDispatch __libc_malloc_default_dispatch
Malloc(iterate),
Malloc(malloc_disable),
Malloc(malloc_enable),
+ Malloc(mallopt),
};
// In a VM process, this is set to 1 after fork()ing out of zygote.
@@ -106,6 +107,14 @@ extern "C" struct mallinfo mallinfo() {
return Malloc(mallinfo)();
}
+extern "C" int mallopt(int param, int value) {
+ auto _mallopt = __libc_globals->malloc_dispatch.mallopt;
+ if (__predict_false(_mallopt != nullptr)) {
+ return _mallopt(param, value);
+ }
+ return Malloc(mallopt)(param, value);
+}
+
extern "C" void* malloc(size_t bytes) {
auto _malloc = __libc_globals->malloc_dispatch.malloc;
if (__predict_false(_malloc != nullptr)) {
@@ -253,6 +262,10 @@ static bool InitMalloc(void* malloc_impl_handler, MallocDispatch* table, const c
prefix, "mallinfo")) {
return false;
}
+ if (!InitMallocFunction<MallocMallopt>(malloc_impl_handler, &table->mallopt,
+ prefix, "mallopt")) {
+ return false;
+ }
if (!InitMallocFunction<MallocMalloc>(malloc_impl_handler, &table->malloc,
prefix, "malloc")) {
return false;
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index 87555a96b..f0cdf82f3 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -70,6 +70,11 @@ extern struct mallinfo mallinfo(void);
*/
extern int malloc_info(int, FILE *);
+/* mallopt options */
+#define M_DECAY_TIME -100
+
+int mallopt(int, int) __INTRODUCED_IN(26);
+
__END_DECLS
#endif /* LIBC_INCLUDE_MALLOC_H_ */
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index 38f8437f4..52698b6f0 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1494,4 +1494,5 @@ LIBC_PLATFORM {
malloc_disable;
malloc_enable;
malloc_iterate;
+ mallopt;
} LIBC_N;
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index afbd0ee4b..db7368ded 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1209,4 +1209,5 @@ LIBC_PLATFORM {
malloc_disable;
malloc_enable;
malloc_iterate;
+ mallopt;
} LIBC_N;
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index 46c835b0b..2e272f5ca 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1335,4 +1335,5 @@ LIBC_PLATFORM {
malloc_disable;
malloc_enable;
malloc_iterate;
+ mallopt;
} LIBC_N;
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index afbd0ee4b..db7368ded 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1209,4 +1209,5 @@ LIBC_PLATFORM {
malloc_disable;
malloc_enable;
malloc_iterate;
+ mallopt;
} LIBC_N;
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index 9417d5620..6598e3d4b 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1334,4 +1334,5 @@ LIBC_PLATFORM {
malloc_disable;
malloc_enable;
malloc_iterate;
+ mallopt;
} LIBC_N;
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index afbd0ee4b..db7368ded 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1209,4 +1209,5 @@ LIBC_PLATFORM {
malloc_disable;
malloc_enable;
malloc_iterate;
+ mallopt;
} LIBC_N;
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index 1ee76897d..329e72505 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -76,6 +76,7 @@ void* debug_memalign(size_t alignment, size_t bytes);
void* debug_realloc(void* pointer, size_t bytes);
void* debug_calloc(size_t nmemb, size_t bytes);
struct mallinfo debug_mallinfo();
+int debug_mallopt(int param, int value);
int debug_posix_memalign(void** memptr, size_t alignment, size_t size);
int debug_iterate(uintptr_t base, size_t size,
void (*callback)(uintptr_t base, size_t size, void* arg), void* arg);
@@ -584,6 +585,10 @@ struct mallinfo debug_mallinfo() {
return g_dispatch->mallinfo();
}
+int debug_mallopt(int param, int value) {
+ return g_dispatch->mallopt(param, value);
+}
+
int debug_posix_memalign(void** memptr, size_t alignment, size_t size) {
if (DebugCallsDisabled()) {
return g_dispatch->posix_memalign(memptr, alignment, size);
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 014b91352..8014f0652 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -58,6 +58,7 @@ void debug_get_malloc_leak_info(uint8_t**, size_t*, size_t*, size_t*, size_t*);
void debug_free_malloc_leak_info(uint8_t*);
struct mallinfo debug_mallinfo();
+int debug_mallopt(int, int);
#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
void* debug_pvalloc(size_t);
@@ -125,6 +126,7 @@ MallocDispatch MallocDebugTest::dispatch = {
nullptr,
nullptr,
nullptr,
+ mallopt,
};
void VerifyAllocCalls() {
@@ -1471,6 +1473,20 @@ TEST_F(MallocDebugTest, debug_mallinfo) {
ASSERT_STREQ("", getFakeLogPrint().c_str());
}
+TEST_F(MallocDebugTest, debug_mallopt) {
+ Init("guard");
+
+ void* pointer = debug_malloc(150);
+ ASSERT_TRUE(pointer != nullptr);
+
+ EXPECT_EQ(0, debug_mallopt(-1000, 1));
+
+ debug_free(pointer);
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
TEST_F(MallocDebugTest, debug_posix_memalign) {
Init("guard");
diff --git a/libc/private/bionic_malloc_dispatch.h b/libc/private/bionic_malloc_dispatch.h
index 02a092f40..cdae466c9 100644
--- a/libc/private/bionic_malloc_dispatch.h
+++ b/libc/private/bionic_malloc_dispatch.h
@@ -45,6 +45,7 @@ typedef void* (*MallocRealloc)(void*, size_t);
typedef int (*MallocIterate)(uintptr_t, size_t, void (*)(uintptr_t, size_t, void*), void*);
typedef void (*MallocMallocDisable)();
typedef void (*MallocMallocEnable)();
+typedef int (*MallocMallopt)(int, int);
#if defined(HAVE_DEPRECATED_MALLOC_FUNCS)
typedef void* (*MallocPvalloc)(size_t);
@@ -69,6 +70,7 @@ struct MallocDispatch {
MallocIterate iterate;
MallocMallocDisable malloc_disable;
MallocMallocEnable malloc_enable;
+ MallocMallopt mallopt;
} __attribute__((aligned(32)));
#endif
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index 8fba1c449..a7b9d52e5 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -500,3 +500,10 @@ TEST(malloc, verify_alignment) {
delete[] values_64;
delete[] values_ldouble;
}
+
+TEST(malloc, mallopt_smoke) {
+ errno = 0;
+ ASSERT_EQ(0, mallopt(-1000, 1));
+ // mallopt doesn't set errno.
+ ASSERT_EQ(0, errno);
+}

View File

@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tim Murray <timmurray@google.com>
Date: Mon, 15 Oct 2018 16:26:56 -0700
Subject: [PATCH] malloc: add M_PURGE mallopt flag
Add a new mallopt flag that purges any pending decaying pages.
Test: boots and works
bug 117795621
Merged-in: Ib250ae2b705b6a368c1efb801d6a7be54e075acb
Change-Id: Ib250ae2b705b6a368c1efb801d6a7be54e075acb
(cherry picked from commit 8a07791fbff0dd014ce5da8d88969d09cd3dcf0b)
---
libc/bionic/jemalloc_wrapper.cpp | 12 ++++++++++++
libc/include/malloc.h | 1 +
2 files changed, 13 insertions(+)
diff --git a/libc/bionic/jemalloc_wrapper.cpp b/libc/bionic/jemalloc_wrapper.cpp
index 266b9660c..b4678d008 100644
--- a/libc/bionic/jemalloc_wrapper.cpp
+++ b/libc/bionic/jemalloc_wrapper.cpp
@@ -79,6 +79,18 @@ int je_mallopt(int param, int value) {
}
}
return 1;
+ } else if (param == M_PURGE) {
+ unsigned narenas;
+ size_t sz = sizeof(unsigned);
+ if (je_mallctl("arenas.narenas", &narenas, &sz, nullptr, 0) != 0) {
+ return 0;
+ }
+ char buffer[100];
+ snprintf(buffer, sizeof(buffer), "arena.%u.purge", narenas);
+ if (je_mallctl(buffer, nullptr, nullptr, nullptr, 0) != 0) {
+ return 0;
+ }
+ return 1;
}
return 0;
}
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index f0cdf82f3..50ae7d6a7 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -72,6 +72,7 @@ extern int malloc_info(int, FILE *);
/* mallopt options */
#define M_DECAY_TIME -100
+#define M_PURGE -101
int mallopt(int, int) __INTRODUCED_IN(26);

View File

@ -0,0 +1,517 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Elliott Hughes <enh@google.com>
Date: Wed, 27 Sep 2017 16:33:35 -0700
Subject: [PATCH] Add <sys/random.h>.
iOS 10 has <sys/random.h> with getentropy, glibc >= 2.25 has
<sys/random.h> with getentropy and getrandom. (glibc also pollutes
<unistd.h>, but that seems like a bad idea.)
Also, all supported devices now have kernels with the getrandom system
call.
We've had these available internally for a while, but it seems like the
time is ripe to expose them.
Bug: http://b/67014255
Test: ran tests
Change-Id: I76dde1e3a2d0bc82777eea437ac193f96964f138
---
libc/SYSCALLS.TXT | 3 +
libc/arch-arm/syscalls/getrandom.S | 16 +++
libc/arch-arm64/syscalls/getrandom.S | 14 ++
libc/arch-mips/syscalls/getrandom.S | 19 +++
libc/arch-mips64/syscalls/getrandom.S | 25 ++++
libc/arch-x86/syscalls/getrandom.S | 39 ++++++
libc/arch-x86_64/syscalls/getrandom.S | 15 +++
libc/include/sys/random.h | 47 +++++++
libc/libc.arm.map | 2 +
libc/libc.arm64.map | 2 +
libc/libc.map.txt | 2 +
libc/libc.mips.map | 2 +
libc/libc.mips64.map | 2 +
libc/libc.x86.map | 2 +
libc/libc.x86_64.map | 2 +
.../android/include/openbsd-compat.h | 8 +-
tests/sys_random_test.cpp | 120 ++++++++++++++++++
17 files changed, 317 insertions(+), 3 deletions(-)
create mode 100644 libc/arch-arm/syscalls/getrandom.S
create mode 100644 libc/arch-arm64/syscalls/getrandom.S
create mode 100644 libc/arch-mips/syscalls/getrandom.S
create mode 100644 libc/arch-mips64/syscalls/getrandom.S
create mode 100644 libc/arch-x86/syscalls/getrandom.S
create mode 100644 libc/arch-x86_64/syscalls/getrandom.S
create mode 100644 libc/include/sys/random.h
create mode 100644 tests/sys_random_test.cpp
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index d5dd2063e..536216dba 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -348,3 +348,6 @@ int clock_gettime(clockid_t, timespec*) arm,mips,mips64
int __clock_gettime:clock_gettime(clockid_t, timespec*) arm64,x86,x86_64
int gettimeofday(timeval*, timezone*) arm,mips,mips64
int __gettimeofday:gettimeofday(timeval*, timezone*) arm64,x86,x86_64
+
+# <sys/random.h>
+ssize_t getrandom(void*, size_t, unsigned) all
diff --git a/libc/arch-arm/syscalls/getrandom.S b/libc/arch-arm/syscalls/getrandom.S
new file mode 100644
index 000000000..3f28af6f0
--- /dev/null
+++ b/libc/arch-arm/syscalls/getrandom.S
@@ -0,0 +1,16 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+ mov ip, r7
+ .cfi_register r7, ip
+ ldr r7, =__NR_getrandom
+ swi #0
+ mov r7, ip
+ .cfi_restore r7
+ cmn r0, #(MAX_ERRNO + 1)
+ bxls lr
+ neg r0, r0
+ b __set_errno_internal
+END(getrandom)
diff --git a/libc/arch-arm64/syscalls/getrandom.S b/libc/arch-arm64/syscalls/getrandom.S
new file mode 100644
index 000000000..c8fe41ffd
--- /dev/null
+++ b/libc/arch-arm64/syscalls/getrandom.S
@@ -0,0 +1,14 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+ mov x8, __NR_getrandom
+ svc #0
+
+ cmn x0, #(MAX_ERRNO + 1)
+ cneg x0, x0, hi
+ b.hi __set_errno_internal
+
+ ret
+END(getrandom)
diff --git a/libc/arch-mips/syscalls/getrandom.S b/libc/arch-mips/syscalls/getrandom.S
new file mode 100644
index 000000000..7a2f3b978
--- /dev/null
+++ b/libc/arch-mips/syscalls/getrandom.S
@@ -0,0 +1,19 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+ .set noreorder
+ .cpload t9
+ li v0, __NR_getrandom
+ syscall
+ bnez a3, 1f
+ move a0, v0
+ j ra
+ nop
+1:
+ la t9,__set_errno_internal
+ j t9
+ nop
+ .set reorder
+END(getrandom)
diff --git a/libc/arch-mips64/syscalls/getrandom.S b/libc/arch-mips64/syscalls/getrandom.S
new file mode 100644
index 000000000..3c5b4673f
--- /dev/null
+++ b/libc/arch-mips64/syscalls/getrandom.S
@@ -0,0 +1,25 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+ .set push
+ .set noreorder
+ li v0, __NR_getrandom
+ syscall
+ bnez a3, 1f
+ move a0, v0
+ j ra
+ nop
+1:
+ move t0, ra
+ bal 2f
+ nop
+2:
+ .cpsetup ra, t1, 2b
+ LA t9,__set_errno_internal
+ .cpreturn
+ j t9
+ move ra, t0
+ .set pop
+END(getrandom)
diff --git a/libc/arch-x86/syscalls/getrandom.S b/libc/arch-x86/syscalls/getrandom.S
new file mode 100644
index 000000000..2e8ebc955
--- /dev/null
+++ b/libc/arch-x86/syscalls/getrandom.S
@@ -0,0 +1,39 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+ pushl %ebx
+ .cfi_def_cfa_offset 8
+ .cfi_rel_offset ebx, 0
+ pushl %ecx
+ .cfi_adjust_cfa_offset 4
+ .cfi_rel_offset ecx, 0
+ pushl %edx
+ .cfi_adjust_cfa_offset 4
+ .cfi_rel_offset edx, 0
+
+ call __kernel_syscall
+ pushl %eax
+ .cfi_adjust_cfa_offset 4
+ .cfi_rel_offset eax, 0
+
+ mov 20(%esp), %ebx
+ mov 24(%esp), %ecx
+ mov 28(%esp), %edx
+ movl $__NR_getrandom, %eax
+ call *(%esp)
+ addl $4, %esp
+
+ cmpl $-MAX_ERRNO, %eax
+ jb 1f
+ negl %eax
+ pushl %eax
+ call __set_errno_internal
+ addl $4, %esp
+1:
+ popl %edx
+ popl %ecx
+ popl %ebx
+ ret
+END(getrandom)
diff --git a/libc/arch-x86_64/syscalls/getrandom.S b/libc/arch-x86_64/syscalls/getrandom.S
new file mode 100644
index 000000000..c5e44a966
--- /dev/null
+++ b/libc/arch-x86_64/syscalls/getrandom.S
@@ -0,0 +1,15 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(getrandom)
+ movl $__NR_getrandom, %eax
+ syscall
+ cmpq $-MAX_ERRNO, %rax
+ jb 1f
+ negl %eax
+ movl %eax, %edi
+ call __set_errno_internal
+1:
+ ret
+END(getrandom)
diff --git a/libc/include/sys/random.h b/libc/include/sys/random.h
new file mode 100644
index 000000000..34756520e
--- /dev/null
+++ b/libc/include/sys/random.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _SYS_RANDOM_H_
+#define _SYS_RANDOM_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#include <linux/random.h>
+
+__BEGIN_DECLS
+
+/* See also arc4random_buf in <stdlib.h>, which is available in all API levels. */
+
+int getentropy(void* __buffer, size_t __buffer_size) __wur __INTRODUCED_IN_FUTURE;
+
+ssize_t getrandom(void* __buffer, size_t __buffer_size, unsigned int __flags) __wur __INTRODUCED_IN_FUTURE;
+
+__END_DECLS
+
+#endif
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index 52698b6f0..f2b84f127 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1483,6 +1483,8 @@ LIBC_PRIVATE {
vfdprintf; # arm x86 mips nobrillo
wait3; # arm x86 mips nobrillo
wcswcs; # arm x86 mips nobrillo
+ getentropy; # future
+ getrandom; # future
} LIBC_N;
LIBC_PLATFORM {
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index db7368ded..284527c08 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1198,6 +1198,8 @@ LIBC_PRIVATE {
free_malloc_leak_info;
get_malloc_leak_info;
gMallocLeakZygoteChild;
+ getentropy; # future
+ getrandom; # future
} LIBC_N;
LIBC_PLATFORM {
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 0e41f6ccb..18354e218 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1509,6 +1509,8 @@ LIBC_PRIVATE {
vfdprintf; # arm x86 mips nobrillo
wait3; # arm x86 mips nobrillo
wcswcs; # arm x86 mips nobrillo
+ getentropy; # future
+ getrandom; # future
} LIBC_N;
LIBC_PLATFORM {
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index 2e272f5ca..2aba50685 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1324,6 +1324,8 @@ LIBC_PRIVATE {
vfdprintf; # arm x86 mips nobrillo
wait3; # arm x86 mips nobrillo
wcswcs; # arm x86 mips nobrillo
+ getentropy; # future
+ getrandom; # future
} LIBC_N;
LIBC_PLATFORM {
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index db7368ded..284527c08 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1198,6 +1198,8 @@ LIBC_PRIVATE {
free_malloc_leak_info;
get_malloc_leak_info;
gMallocLeakZygoteChild;
+ getentropy; # future
+ getrandom; # future
} LIBC_N;
LIBC_PLATFORM {
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index 6598e3d4b..c6282457e 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1323,6 +1323,8 @@ LIBC_PRIVATE {
vfdprintf; # arm x86 mips nobrillo
wait3; # arm x86 mips nobrillo
wcswcs; # arm x86 mips nobrillo
+ getentropy; # future
+ getrandom; # future
} LIBC_N;
LIBC_PLATFORM {
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index db7368ded..284527c08 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1198,6 +1198,8 @@ LIBC_PRIVATE {
free_malloc_leak_info;
get_malloc_leak_info;
gMallocLeakZygoteChild;
+ getentropy; # future
+ getrandom; # future
} LIBC_N;
LIBC_PLATFORM {
diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h
index caea45a93..ed388144a 100644
--- a/libc/upstream-openbsd/android/include/openbsd-compat.h
+++ b/libc/upstream-openbsd/android/include/openbsd-compat.h
@@ -22,6 +22,11 @@
#include <sys/cdefs.h>
#include <stddef.h> // For size_t.
+// TODO: libandroid_support uses this file, so we need to wait for
+// <sys/random.h> to be in the NDK headers before we can lose this declaration.
+//#include <sys/random.h> // For getentropy.
+int getentropy(void*, size_t);
+
/* Redirect internal C library calls to the public function. */
#define _err err
#define _errx errx
@@ -65,9 +70,6 @@
*/
#define _PATH_TMP "/data/local/tmp/"
-/* We have OpenBSD's getentropy_linux.c, but we don't mention getentropy in any header. */
-__LIBC_HIDDEN__ extern int getentropy(void*, size_t);
-
/* OpenBSD has this as API, but we just use it internally. */
__LIBC_HIDDEN__ void* reallocarray(void*, size_t, size_t);
diff --git a/tests/sys_random_test.cpp b/tests/sys_random_test.cpp
new file mode 100644
index 000000000..a25490c67
--- /dev/null
+++ b/tests/sys_random_test.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// <sys/random.h> was only added as of glibc version 2.25.
+// Don't try to compile this code on older glibc versions.
+
+#include <sys/cdefs.h>
+#if defined(__BIONIC__)
+ #define HAVE_SYS_RANDOM 1
+#elif defined(__GLIBC_PREREQ)
+ #if __GLIBC_PREREQ(2, 25)
+ #define HAVE_SYS_RANDOM 1
+ #endif
+#endif
+
+
+#if defined(HAVE_SYS_RANDOM)
+#include <sys/random.h>
+#endif
+
+#include <errno.h>
+#include <gtest/gtest.h>
+
+TEST(sys_random, getentropy) {
+#if defined(HAVE_SYS_RANDOM)
+ char buf1[64];
+ char buf2[64];
+
+ ASSERT_EQ(0, getentropy(buf1, sizeof(buf1)));
+ ASSERT_EQ(0, getentropy(buf2, sizeof(buf2)));
+ ASSERT_TRUE(memcmp(buf1, buf2, sizeof(buf1)) != 0);
+#else
+ GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getentropy_EFAULT) {
+#if defined(HAVE_SYS_RANDOM)
+ errno = 0;
+ ASSERT_EQ(-1, getentropy(nullptr, 1));
+ ASSERT_EQ(EFAULT, errno);
+#else
+ GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getentropy_EIO) {
+#if defined(HAVE_SYS_RANDOM)
+ char buf[BUFSIZ];
+ static_assert(BUFSIZ > 256, "BUFSIZ <= 256!");
+
+ errno = 0;
+ ASSERT_EQ(-1, getentropy(buf, sizeof(buf)));
+ ASSERT_EQ(EIO, errno);
+#else
+ GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getrandom) {
+#if defined(HAVE_SYS_RANDOM)
+ if (getrandom(nullptr, 0, 0) == -1 && errno == ENOSYS) {
+ GTEST_LOG_(INFO) << "This test requires a >= 3.17 kernel with getrandom(2).\n";
+ return;
+ }
+
+ char buf1[64];
+ char buf2[64];
+
+ ASSERT_EQ(64, getrandom(buf1, sizeof(buf1), 0));
+ ASSERT_EQ(64, getrandom(buf2, sizeof(buf2), 0));
+ ASSERT_TRUE(memcmp(buf1, buf2, sizeof(buf1)) != 0);
+#else
+ GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getrandom_EFAULT) {
+#if defined(HAVE_SYS_RANDOM)
+ if (getrandom(nullptr, 0, 0) == -1 && errno == ENOSYS) {
+ GTEST_LOG_(INFO) << "This test requires a >= 3.17 kernel with getrandom(2).\n";
+ return;
+ }
+
+ errno = 0;
+ ASSERT_EQ(-1, getrandom(nullptr, 256, 0));
+ ASSERT_EQ(EFAULT, errno);
+#else
+ GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}
+
+TEST(sys_random, getrandom_EINVAL) {
+#if defined(HAVE_SYS_RANDOM)
+ if (getrandom(nullptr, 0, 0) == -1 && errno == ENOSYS) {
+ GTEST_LOG_(INFO) << "This test requires a >= 3.17 kernel with getrandom(2).\n";
+ return;
+ }
+
+ errno = 0;
+ char buf[64];
+ ASSERT_EQ(-1, getrandom(buf, sizeof(buf), ~0));
+ ASSERT_EQ(EINVAL, errno);
+#else
+ GTEST_LOG_(INFO) << "This test requires a C library with <sys/random.h>.\n";
+#endif
+}

View File

@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Micay <danielmicay@gmail.com>
Date: Wed, 5 Dec 2018 09:29:25 -0500
Subject: [PATCH] avoid setting RLIMIT_AS with hardened malloc
This needs to be ported to a better mechanism like memory control groups
in order to remain compatible with hardening mechanisms based on large
PROT_NONE address space reservations.
Change-Id: Ibfb7164d764fcb9244055953bedc9a1c424cedcb
---
media/libmedia/MediaUtils.cpp | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/media/libmedia/MediaUtils.cpp b/media/libmedia/MediaUtils.cpp
index a02ca65a7a..bb93e3d27f 100644
--- a/media/libmedia/MediaUtils.cpp
+++ b/media/libmedia/MediaUtils.cpp
@@ -31,6 +31,14 @@ void limitProcessMemory(
size_t numberOfBytes,
size_t percentageOfTotalMem) {
+#ifdef __LP64__
+ // This needs to be ported to a better mechanism like memory control groups
+ // in order to remain compatible with hardening mechanisms based on large
+ // PROT_NONE address space reservations.
+ ALOGW("Running with hardened malloc implementation, skip enforcing memory limitations.");
+ return;
+#endif
+
long pageSize = sysconf(_SC_PAGESIZE);
long numPages = sysconf(_SC_PHYS_PAGES);
size_t maxMem = SIZE_MAX;

View File

@ -0,0 +1,22 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Micay <danielmicay@gmail.com>
Date: Thu, 13 Dec 2018 09:26:25 -0500
Subject: [PATCH] increase max_map_count for hardened malloc
---
rootdir/init.rc | 2 ++
1 file changed, 2 insertions(+)
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 4abc6d1a8..93299148c 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -524,6 +524,8 @@ on boot
chown root system /sys/module/lowmemorykiller/parameters/minfree
chmod 0664 /sys/module/lowmemorykiller/parameters/minfree
+ write /proc/sys/vm/max_map_count 524240
+
# Tweak background writeout
write /proc/sys/vm/dirty_expire_centisecs 200
write /proc/sys/vm/dirty_background_ratio 5

View File

@ -61,6 +61,12 @@ fi;
if enterAndClear "bionic"; then
applyPatch "$DOS_PATCHES_COMMON/android_bionic/0001-Wildcard_Hosts.patch"; #Support wildcards in cached hosts file (backport from 16.0+) (tdm)
if [ "$DOS_GRAPHENE_MALLOC_STAGING" = true ]; then
applyPatch "$DOS_PATCHES/android_bionic/0001-HM-Use_HM.patch"; #(GrapheneOS)
applyPatch "$DOS_PATCHES/android_bionic/0002-Add_Decay_Timer.patch"; #Add support for modifying decay timer.
applyPatch "$DOS_PATCHES/android_bionic/0003-Add_M_PURGE.patch"; #malloc: add M_PURGE mallopt flag
applyPatch "$DOS_PATCHES/android_bionic/0004-Add_random.h.patch"; #Add <sys/random.h>.
fi;
fi;
if enterAndClear "bootable/recovery"; then
@ -110,6 +116,29 @@ applyPatch "$DOS_PATCHES/android_external_freetype/0001-makefile.patch"; #Add An
applyPatch "$DOS_PATCHES/android_external_freetype/0002-fixup.patch"; #Enable png and zlib support to Android.mk (syphyr)
fi;
if [ "$DOS_GRAPHENE_MALLOC_STAGING" = true ]; then
if enterAndClear "external/hardened_malloc"; then
applyPatch "$DOS_PATCHES_COMMON/android_external_hardened_malloc-modern/0001-Broken_Cameras-1.patch"; #Workarounds for Pixel 3 SoC era camera driver bugs (GrapheneOS)
applyPatch "$DOS_PATCHES_COMMON/android_external_hardened_malloc-modern/0001-Broken_Cameras-2.patch"; #Expand workaround to all camera executables (DivestOS)
applyPatch "$DOS_PATCHES_COMMON/android_external_hardened_malloc-modern/0002-Broken_Displays.patch"; #Add workaround for OnePlus 8 & 9 display driver crash (DivestOS)
applyPatch "$DOS_PATCHES_COMMON/android_external_hardened_malloc-modern/0003-Broken_Audio.patch"; #Workaround for audio service sorting bug (GrapheneOS)
sed -i 's/34359738368/2147483648/' Android.bp; #revert 48-bit address space requirement
sed -i -e '76,78d;' Android.bp; #fix compile under A13
sed -i -e '22,24d;' androidtest/Android.bp; #fix compile under A12
awk -i inplace '!/vendor_ramdisk_available/' Android.bp; #fix compile under A11
rm -rfv androidtest;
sed -i -e '76,78d;' Android.bp; #fix compile under A10
awk -i inplace '!/ramdisk_available/' Android.bp;
git revert --no-edit 8974af86d12f7e29b54b5090133ab3d7eea0e519;
mv include/h_malloc.h .
awk -i inplace '!/recovery_available/' Android.bp; #fix compile under A8
awk -i inplace '!/system_shared_libs/' Android.bp;
sed -i 's/c17/c11/' Android.bp;
git revert --no-edit a28da3c65aed0528036da9ebd33e0c05b2c5884a
sed -i 's/struct mallinfo info = {0};/struct mallinfo info = {};/' h_malloc.c;
fi;
fi;
if enterAndClear "external/libavc"; then
applyPatch "$DOS_PATCHES/android_external_libavc/315711.patch"; #n-asb-2021-09 Decoder: Update check for increment u2_cur_slice_num
applyPatch "$DOS_PATCHES/android_external_libavc/323462.patch"; #n-asb-2022-02 Move slice increments after completing header parsing
@ -172,6 +201,7 @@ applyPatch "$DOS_PATCHES/android_frameworks_av/373035.patch"; #n-asb-2023-11 Fix
applyPatch "$DOS_PATCHES/android_frameworks_av/381852.patch"; #n-asb-2024-02 Update mtp packet buffer
applyPatch "$DOS_PATCHES/android_frameworks_av/385240.patch"; #n-asb-2024-03 Fix out of bounds read and write in onQueueFilled in outQueue
applyPatch "$DOS_PATCHES/android_frameworks_av/385243.patch"; #n-asb-2024-03 Validate OMX Params for VPx encoders
if [ "$DOS_GRAPHENE_MALLOC_STAGING" = true ]; then applyPatch "$DOS_PATCHES/android_frameworks_av/0001-HM-No_RLIMIT_AS.patch"; fi; #(GrapheneOS)
fi;
if enterAndClear "frameworks/base"; then
@ -569,6 +599,7 @@ applyPatch "$DOS_PATCHES/android_system_core/332457.patch"; #n-asb-2022-06 Backp
if [ "$DOS_HOSTS_BLOCKING" = true ]; then cat "$DOS_HOSTS_FILE" >> rootdir/etc/hosts; fi; #Merge in our HOSTS file
git revert --no-edit 0217dddeb5c16903c13ff6c75213619b79ea622b d7aa1231b6a0631f506c0c23816f2cd81645b15f; #Always update recovery XXX: This doesn't seem to work
applyPatch "$DOS_PATCHES/android_system_core/0001-Harden.patch"; #Harden mounts with nodev/noexec/nosuid + misc sysctl changes (GrapheneOS)
if [ "$DOS_GRAPHENE_MALLOC_STAGING" = true ]; then applyPatch "$DOS_PATCHES/android_system_core/0002-HM-Increase_vm_mmc.patch"; fi; #(GrapheneOS)
sed -i 's/!= 2048/< 2048/' libmincrypt/tools/DumpPublicKey.java; #Allow 4096-bit keys
fi;

View File

@ -62,7 +62,7 @@ export DOS_GPS_GLONASS_FORCED=false; #Enables GLONASS on all devices
export DOS_DEFCONFIG_DISABLER=true; #Enables the disablement of various kernel options
export DOS_GRAPHENE_BIONIC=true; #Enables the bionic hardening patchset on 16.0+17.1+18.1+19.1+20.0
export DOS_GRAPHENE_CONSTIFY=true; #Enables 'Constify JNINativeMethod tables' patchset on 16.0+17.1+18.1+19.1+20.0
export DOS_GRAPHENE_MALLOC=true; #Enables use of GrapheneOS' hardened memory allocator on 64-bit platforms on 16.0+17.1+18.1+19.1+20.0
export DOS_GRAPHENE_MALLOC=true; #Enables use of GrapheneOS' hardened memory allocator on 64-bit platforms on 15.1+16.0+17.1+18.1+19.1+20.0
export DOS_GRAPHENE_EXEC=true; #Enables use of GrapheneOS' exec spawning feature on 16.0+17.1+18.1+19.1+20.0
export DOS_HOSTS_BLOCKING=true; #Set false to prevent inclusion of a HOSTS file
export DOS_HOSTS_BLOCKING_LIST="https://divested.dev/hosts-wildcards"; #Must be in the format "127.0.0.1 bad.domain.tld"