Compare commits

...

4 commits

Author SHA1 Message Date
cgzones
8d4b64b45a
Merge 96836f463b into d4e40af550 2026-01-11 05:43:47 +01:00
bravesasha
d4e40af550 Update LICENSE 2026-01-07 03:07:41 -05:00
qikp0
bb9187b94c Android 16 QPR2 is now the active branch of AOSP 2026-01-03 14:47:39 -05:00
Christian Göttsche
96836f463b linux: make use of mseal(2)
Instead of protecting the global read-only data structure after startup
via the read-only flag, which can be reverted, use the in Linux 6.10
introduced irreversible syscall mseal(2).
2024-07-27 11:37:59 +02:00
5 changed files with 26 additions and 2 deletions

View file

@ -1,4 +1,4 @@
Copyright © 2018-2025 GrapheneOS Copyright © 2018-2026 GrapheneOS
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -83,7 +83,7 @@ there will be custom integration offering better performance in the future
along with other hardening for the C standard library implementation. along with other hardening for the C standard library implementation.
For Android, only the current generation, actively developed maintenance branch of the Android For Android, only the current generation, actively developed maintenance branch of the Android
Open Source Project will be supported, which currently means `android16-qpr1-release`. Open Source Project will be supported, which currently means `android16-qpr2-release`.
## Testing ## Testing

View file

@ -1295,7 +1295,12 @@ COLD static void init_slow_path(void) {
atomic_store_explicit(&ro.slab_region_end, slab_region_end, memory_order_release); atomic_store_explicit(&ro.slab_region_end, slab_region_end, memory_order_release);
#if defined(__ANDROID__) && defined(HAS_ARM_MTE)
/* Do not seal to support disabling memory tagging */
if (unlikely(memory_protect_ro(&ro, sizeof(ro)))) { if (unlikely(memory_protect_ro(&ro, sizeof(ro)))) {
#else
if (unlikely(memory_protect_seal(&ro, sizeof(ro)))) {
#endif
fatal_error("failed to protect allocator data"); fatal_error("failed to protect allocator data");
} }
memory_set_name(&ro, sizeof(ro), "malloc read-only after init"); memory_set_name(&ro, sizeof(ro), "malloc read-only after init");

View file

@ -1,6 +1,8 @@
#include <errno.h> #include <errno.h>
#include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/syscall.h>
#ifdef LABEL_MEMORY #ifdef LABEL_MEMORY
#include <sys/prctl.h> #include <sys/prctl.h>
@ -91,6 +93,22 @@ bool memory_protect_rw_metadata(void *ptr, size_t size) {
return memory_protect_prot(ptr, size, PROT_READ|PROT_WRITE, get_metadata_key()); return memory_protect_prot(ptr, size, PROT_READ|PROT_WRITE, get_metadata_key());
} }
COLD bool memory_protect_seal(void *ptr, size_t size) {
#if defined(__linux__) && defined(__NR_mseal)
/* supported since Linux 6.10 */
int ret = syscall(__NR_mseal, ptr, size, 0);
if (ret == 0)
return false;
if (unlikely(errno == ENOMEM))
return true;
if (errno == ENOSYS)
return memory_protect_ro(ptr, size);
fatal_error("non-ENOMEM and non-ENOSYS mseal failure");
#else
return memory_protect_ro(ptr, size);
#endif
}
#ifdef HAVE_COMPATIBLE_MREMAP #ifdef HAVE_COMPATIBLE_MREMAP
bool memory_remap(void *old, size_t old_size, size_t new_size) { bool memory_remap(void *old, size_t old_size, size_t new_size) {
void *ptr = mremap(old, old_size, new_size, 0); void *ptr = mremap(old, old_size, new_size, 0);

View file

@ -22,6 +22,7 @@ bool memory_unmap(void *ptr, size_t size);
bool memory_protect_ro(void *ptr, size_t size); bool memory_protect_ro(void *ptr, size_t size);
bool memory_protect_rw(void *ptr, size_t size); bool memory_protect_rw(void *ptr, size_t size);
bool memory_protect_rw_metadata(void *ptr, size_t size); bool memory_protect_rw_metadata(void *ptr, size_t size);
bool memory_protect_seal(void *ptr, size_t size);
#ifdef HAVE_COMPATIBLE_MREMAP #ifdef HAVE_COMPATIBLE_MREMAP
bool memory_remap(void *old, size_t old_size, size_t new_size); bool memory_remap(void *old, size_t old_size, size_t new_size);
bool memory_remap_fixed(void *old, size_t old_size, void *new, size_t new_size); bool memory_remap_fixed(void *old, size_t old_size, void *new, size_t new_size);