--- a/src/closures.c +++ b/src/closures.c @@ -458,29 +458,19 @@ dlmmap (void *start, size_t length, int printf ("mapping in %zi\n", length); #endif - if (execfd == -1 && !is_selinux_enabled ()) + ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset); + if (ptr != MFAIL || (errno != EPERM && errno != EACCES)) { - ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset); - - if (ptr != MFAIL || (errno != EPERM && errno != EACCES)) - /* Cool, no need to mess with separate segments. */ - return ptr; - - /* If MREMAP_DUP is ever introduced and implemented, try mmap - with ((prot & ~PROT_WRITE) | PROT_EXEC) and mremap with - MREMAP_DUP and prot at this point. */ + return ptr; } - - if (execsize == 0 || execfd == -1) + else { - pthread_mutex_lock (&open_temp_exec_file_mutex); - ptr = dlmmap_locked (start, length, prot, flags, offset); - pthread_mutex_unlock (&open_temp_exec_file_mutex); - - return ptr; + /* Retry without PROT_EXEC. This should work in most cases. */ + ptr = mmap (start, length, prot, flags, fd, offset); + if (ptr != MFAIL || (errno != EPERM && errno != EACCES)) + return ptr; } - - return dlmmap_locked (start, length, prot, flags, offset); + return MFAIL; } /* Release memory at the given address, as well as the corresponding