remove workaround for Linux kernel MPK fork bug
parent
c75dcb9d9c
commit
19365c25d6
|
@ -83,6 +83,13 @@ along with other hardening for the C standard library implementation.
|
||||||
For Android, only current generation Android Open Source Project branches will
|
For Android, only current generation Android Open Source Project branches will
|
||||||
be supported, which currently means `android10-release`.
|
be supported, which currently means `android10-release`.
|
||||||
|
|
||||||
|
The Linux kernel's implementation of Memory Protection Keys was severely broken
|
||||||
|
before Linux 5.0. The `CONFIG_SEAL_METADATA` feature should only be enabled for
|
||||||
|
use on kernels newer than 5.0 or longterm branches with a backport of the [fix
|
||||||
|
for the
|
||||||
|
issue](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a31e184e4f69965c99c04cc5eb8a4920e0c63737).
|
||||||
|
This issue was discovered and reported by the hardened\_malloc project.
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
### Individual Applications
|
### Individual Applications
|
||||||
|
@ -983,7 +990,6 @@ Additional system calls when `CONFIG_SEAL_METADATA=true` is set:
|
||||||
* `pkey_alloc`
|
* `pkey_alloc`
|
||||||
* `pkey_mprotect` instead of `mprotect` with an additional `pkey` parameter,
|
* `pkey_mprotect` instead of `mprotect` with an additional `pkey` parameter,
|
||||||
but otherwise the same (regular `mprotect` is never called)
|
but otherwise the same (regular `mprotect` is never called)
|
||||||
* `uname` (to detect old buggy kernel versions)
|
|
||||||
|
|
||||||
Additional system calls for Android builds with `LABEL_MEMORY`:
|
Additional system calls for Android builds with `LABEL_MEMORY`:
|
||||||
|
|
||||||
|
|
19
h_malloc.c
19
h_malloc.c
|
@ -80,7 +80,6 @@ static union {
|
||||||
struct region_metadata *regions[2];
|
struct region_metadata *regions[2];
|
||||||
#ifdef USE_PKEY
|
#ifdef USE_PKEY
|
||||||
int metadata_pkey;
|
int metadata_pkey;
|
||||||
bool pkey_state_preserved_on_fork;
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
char padding[PAGE_SIZE];
|
char padding[PAGE_SIZE];
|
||||||
|
@ -1023,15 +1022,6 @@ static void full_unlock(void) {
|
||||||
static void post_fork_child(void) {
|
static void post_fork_child(void) {
|
||||||
thread_unseal_metadata();
|
thread_unseal_metadata();
|
||||||
|
|
||||||
#ifdef USE_PKEY
|
|
||||||
if (!ro.pkey_state_preserved_on_fork) {
|
|
||||||
// disable sealing to work around kernel bug causing fork to lose the pkey setup
|
|
||||||
memory_protect_rw(&ro, sizeof(ro));
|
|
||||||
ro.metadata_pkey = -1;
|
|
||||||
memory_protect_ro(&ro, sizeof(ro));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mutex_init(&ro.region_allocator->lock);
|
mutex_init(&ro.region_allocator->lock);
|
||||||
random_state_init(&ro.region_allocator->rng);
|
random_state_init(&ro.region_allocator->rng);
|
||||||
for (unsigned arena = 0; arena < N_ARENA; arena++) {
|
for (unsigned arena = 0; arena < N_ARENA; arena++) {
|
||||||
|
@ -1066,15 +1056,6 @@ COLD static void init_slow_path(void) {
|
||||||
|
|
||||||
#ifdef USE_PKEY
|
#ifdef USE_PKEY
|
||||||
ro.metadata_pkey = pkey_alloc(0, 0);
|
ro.metadata_pkey = pkey_alloc(0, 0);
|
||||||
|
|
||||||
// pkey state is not preserved on fork before Linux 5.0 unless the patch was backported
|
|
||||||
struct utsname uts;
|
|
||||||
if (uname(&uts) == 0) {
|
|
||||||
unsigned long version = strtoul(uts.release, NULL, 10);
|
|
||||||
if (version >= 5) {
|
|
||||||
ro.pkey_state_preserved_on_fork = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sysconf(_SC_PAGESIZE) != PAGE_SIZE) {
|
if (sysconf(_SC_PAGESIZE) != PAGE_SIZE) {
|
||||||
|
|
Loading…
Reference in New Issue