remove workaround for Linux kernel MPK fork bug

pull/109/head
Daniel Micay 2020-04-24 02:51:10 -04:00
parent c75dcb9d9c
commit 19365c25d6
2 changed files with 7 additions and 20 deletions

View File

@ -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`:

View File

@ -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) {