From 19365c25d62329e397699c21bf1acaf170e22235 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 24 Apr 2020 02:51:10 -0400 Subject: [PATCH] remove workaround for Linux kernel MPK fork bug --- README.md | 8 +++++++- h_malloc.c | 19 ------------------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 9a0aaad..7966b8d 100644 --- a/README.md +++ b/README.md @@ -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 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 ### Individual Applications @@ -983,7 +990,6 @@ Additional system calls when `CONFIG_SEAL_METADATA=true` is set: * `pkey_alloc` * `pkey_mprotect` instead of `mprotect` with an additional `pkey` parameter, 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`: diff --git a/h_malloc.c b/h_malloc.c index 998de6f..2251686 100644 --- a/h_malloc.c +++ b/h_malloc.c @@ -80,7 +80,6 @@ static union { struct region_metadata *regions[2]; #ifdef USE_PKEY int metadata_pkey; - bool pkey_state_preserved_on_fork; #endif }; char padding[PAGE_SIZE]; @@ -1023,15 +1022,6 @@ static void full_unlock(void) { static void post_fork_child(void) { 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); random_state_init(&ro.region_allocator->rng); for (unsigned arena = 0; arena < N_ARENA; arena++) { @@ -1066,15 +1056,6 @@ COLD static void init_slow_path(void) { #ifdef USE_PKEY 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 if (sysconf(_SC_PAGESIZE) != PAGE_SIZE) {