This is the mail archive of the
libffi-discuss@sourceware.org
mailing list for the libffi project.
[PATCH] Add support for PaX enable kernels (MPROTECT)
- From: Magnus Granberg <zorry at gentoo dot org>
- To: libffi-discuss at sourceware dot org
- Date: Sat, 22 Sep 2012 16:08:18 +0200
- Subject: [PATCH] Add support for PaX enable kernels (MPROTECT)
Hi
When we use the libffi on PaX enable kernels with MPROTECT enable we can't use
PROT_EXEC for it get killed. We use the EMUTRAMP Option in PaX enable kernels
to make it work and we need some code added to the src/closures.c to make it
work.The new configure option will turn the code of or on.
You can read more of the problem we have on
https://bugs.gentoo.org/show_bug.cgi?id=329499
Gentoo Hardened Project
Magnus Granberg
Changelog
2012-09-22 Magnus Granberg <zorry@gentoo.org>
Pavel Labushev <pavel.labushev@runbox.ru>
* configure.ac New options pax_emutramp
* configure Regenrated
* fficonfig.h.in Regenrated
/src
* closures.c New function emutramp_enabled_check() and checks
----
--- a/configure.ac 2012-09-17 16:51:53.188615663 +0200
+++ b/configure.ac 2012-09-19 23:20:49.321666120 +0200
@@ -347,6 +347,13 @@ if test x$TARGET = xX86_WIN64; then
fi
fi
+# On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC.
+AC_ARG_ENABLE(pax_emutramp,
+ [ --enable-pax_emutramp enable pax emulated trampolines, for we can't use PROT_EXEC],
+ if test "$enable_pax_emutramp" = "yes"; then
+ AC_DEFINE(FFI_MMAP_EXEC_EMUTRAMP_PAX, 1,
+ [Define this if you want to enable pax emulated trampolines])
+ fi)
FFI_EXEC_TRAMPOLINE_TABLE=0
case "$target" in
--- a/src/closures.c 2012-09-19 23:37:09.648695333 +0200
+++ b/src/closures.c 2012-09-19 23:19:30.000000000 +0200
@@ -172,6 +172,27 @@ selinux_enabled_check (void)
#endif /* !FFI_MMAP_EXEC_SELINUX */
+/* On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. */
+#ifdef FFI_MMAP_EXEC_EMUTRAMP_PAX
+#include <stdlib.h>
+
+static int emutramp_enabled = -1;
+
+static int
+emutramp_enabled_check (void)
+{
+ if (getenv ("FFI_DISABLE_EMUTRAMP") == NULL)
+ return 1;
+ else
+ return 0;
+}
+
+#define is_emutramp_enabled() (emutramp_enabled >= 0 ? emutramp_enabled \
+ : (emutramp_enabled = emutramp_enabled_check ()))
+#else
+#define is_emutramp_enabled() 0
+#endif /* FFI_MMAP_EXEC_EMUTRAMP_PAX */
+
#elif defined (__CYGWIN__) || defined(__INTERIX)
#include <sys/mman.h>
@@ -458,6 +479,12 @@ dlmmap (void *start, size_t length, int
printf ("mapping in %zi\n", length);
#endif
+ if (execfd == -1 && is_emutramp_enabled ())
+ {
+ ptr = mmap (start, length, prot & ~PROT_EXEC, flags, fd, offset);
+ return ptr;
+ }
+
if (execfd == -1 && !is_selinux_enabled ())
{
ptr = mmap (start, length, prot | PROT_EXEC, flags, fd, offset);