pax-dlmmap.patch (4236B)
1 From 48d2e46528fb6e621d95a7fa194069fd136b712d Mon Sep 17 00:00:00 2001 2 From: =?UTF-8?q?Stefan=20B=C3=BChler?= <buehler@cert.uni-stuttgart.de> 3 Date: Wed, 7 Sep 2016 15:49:48 +0200 4 Subject: [PATCH 1/2] dlmmap_locked always needs locking as it always modifies 5 execsize 6 7 --- 8 src/closures.c | 13 ++++--------- 9 1 file changed, 4 insertions(+), 9 deletions(-) 10 11 diff --git a/src/closures.c b/src/closures.c 12 index 2e0ffb45..04d6e27f 100644 13 --- a/src/closures.c 14 +++ b/src/closures.c 15 @@ -769,16 +769,11 @@ dlmmap (void *start, size_t length, int prot, 16 MREMAP_DUP and prot at this point. */ 17 } 18 19 - if (execsize == 0 || execfd == -1) 20 - { 21 - pthread_mutex_lock (&open_temp_exec_file_mutex); 22 - ptr = dlmmap_locked (start, length, prot, flags, offset); 23 - pthread_mutex_unlock (&open_temp_exec_file_mutex); 24 + pthread_mutex_lock (&open_temp_exec_file_mutex); 25 + ptr = dlmmap_locked (start, length, prot, flags, offset); 26 + pthread_mutex_unlock (&open_temp_exec_file_mutex); 27 28 - return ptr; 29 - } 30 - 31 - return dlmmap_locked (start, length, prot, flags, offset); 32 + return ptr; 33 } 34 35 /* Release memory at the given address, as well as the corresponding 36 37 From 7aad5f895e2dfdb79d2ef67e1b231d21063e6511 Mon Sep 17 00:00:00 2001 38 From: =?UTF-8?q?Stefan=20B=C3=BChler?= <buehler@cert.uni-stuttgart.de> 39 Date: Wed, 7 Sep 2016 15:50:54 +0200 40 Subject: [PATCH 2/2] ignore PaX EMUTRAMP flag; instead check for MPROTECT 41 42 - code using ffi_closure_alloc doesn't necessarily generate gcc compatible trampolines; only those are allowed by PaX 43 - if MPROTECT is enabled use the same workaround as is used for SELinux (double mmap()) 44 --- 45 src/closures.c | 29 +++++++++++++---------------- 46 1 file changed, 13 insertions(+), 16 deletions(-) 47 48 diff --git a/src/closures.c b/src/closures.c 49 index 04d6e27f..babecc1a 100644 50 --- a/src/closures.c 51 +++ b/src/closures.c 52 @@ -401,14 +401,15 @@ selinux_enabled_check (void) 53 54 #endif /* !FFI_MMAP_EXEC_SELINUX */ 55 56 -/* On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. */ 57 +/* On PaX enable kernels that have MPROTECT enabled we can't use PROT_EXEC. */ 58 #ifdef FFI_MMAP_EXEC_EMUTRAMP_PAX 59 #include <stdlib.h> 60 61 -static int emutramp_enabled = -1; 62 +/* -1: not read yet; 0: no PaX or MPROTECT disabled; 1: MPROTECT enabled. */ 63 +static int mprotect_enabled = -1; 64 65 static int 66 -emutramp_enabled_check (void) 67 +mprotect_enabled_check (void) 68 { 69 char *buf = NULL; 70 size_t len = 0; 71 @@ -422,9 +423,7 @@ emutramp_enabled_check (void) 72 while (getline (&buf, &len, f) != -1) 73 if (!strncmp (buf, "PaX:", 4)) 74 { 75 - char emutramp; 76 - if (sscanf (buf, "%*s %*c%c", &emutramp) == 1) 77 - ret = (emutramp == 'E'); 78 + ret = (NULL != strchr (buf + 4, 'M')); 79 break; 80 } 81 free (buf); 82 @@ -432,8 +431,9 @@ emutramp_enabled_check (void) 83 return ret; 84 } 85 86 -#define is_emutramp_enabled() (emutramp_enabled >= 0 ? emutramp_enabled \ 87 - : (emutramp_enabled = emutramp_enabled_check ())) 88 +#define is_mprotect_enabled() (mprotect_enabled >= 0 ? mprotect_enabled \ 89 + : (mprotect_enabled = mprotect_enabled_check ())) 90 + 91 #endif /* FFI_MMAP_EXEC_EMUTRAMP_PAX */ 92 93 #elif defined (__CYGWIN__) || defined(__INTERIX) 94 @@ -446,7 +446,7 @@ emutramp_enabled_check (void) 95 #endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */ 96 97 #ifndef FFI_MMAP_EXEC_EMUTRAMP_PAX 98 -#define is_emutramp_enabled() 0 99 +#define is_mprotect_enabled() 0 100 #endif /* FFI_MMAP_EXEC_EMUTRAMP_PAX */ 101 102 /* Declare all functions defined in dlmalloc.c as static. */ 103 @@ -750,13 +750,10 @@ dlmmap (void *start, size_t length, int prot, 104 && flags == (MAP_PRIVATE | MAP_ANONYMOUS) 105 && fd == -1 && offset == 0); 106 107 - if (execfd == -1 && is_emutramp_enabled ()) 108 - { 109 - ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset); 110 - return ptr; 111 - } 112 - 113 - if (execfd == -1 && !is_selinux_enabled ()) 114 + /* -1 != execfd hints that we already decided to use dlmmap_locked 115 + last time. If PaX MPROTECT or SELinux is active fallback to 116 + dlmmap_locked. */ 117 + if (execfd == -1 && !is_mprotect_enabled () && !is_selinux_enabled ()) 118 { 119 ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset); 120