From 0194e4a03c394f0bb85cba78ac12f10c480c5670 Mon Sep 17 00:00:00 2001 From: Kevin Tanguy Date: Tue, 17 Jan 2017 21:05:14 +0100 Subject: Add support for recent kmem_cache_create_usercopy SLAB_USERCOPY flag was used to indicate PAX not to kill copies from kernel to userland. With recent grsecurity patchset and CONFIG_GRKERNSEC_HIDESYM that enables CONFIG_PAX_USERCOPY zfs would panic. Handle newer API while keeping old one functional. Tested-by: RageLtMan Reviewed-by: spendergrsec Reviewed-by: Brian Behlendorf Signed-off-by: Kevin Tanguy Closes #595 --- config/spl-build.m4 | 37 +++++++++++++++++++++++++++++++++++++ module/spl/spl-kmem-cache.c | 13 +++++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/config/spl-build.m4 b/config/spl-build.m4 index 7e2e7a0a9..8d0e8aba3 100644 --- a/config/spl-build.m4 +++ b/config/spl-build.m4 @@ -50,6 +50,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ SPL_AC_MUTEX_OWNER SPL_AC_INODE_LOCK SPL_AC_GROUP_INFO_GID + SPL_AC_KMEM_CACHE_CREATE_USERCOPY ]) AC_DEFUN([SPL_AC_MODULE_SYMVERS], [ @@ -1597,3 +1598,39 @@ AC_DEFUN([SPL_AC_GROUP_INFO_GID], [ ]) EXTRA_KCFLAGS="$tmp_flags" ]) + +dnl # +dnl # grsecurity API change, +dnl # kmem_cache_create() with SLAB_USERCOPY flag replaced by +dnl # kmem_cache_create_usercopy(). +dnl # +AC_DEFUN([SPL_AC_KMEM_CACHE_CREATE_USERCOPY], [ + AC_MSG_CHECKING([whether kmem_cache_create_usercopy() exists]) + tmp_flags="$EXTRA_KCFLAGS" + EXTRA_KCFLAGS="-Werror" + SPL_LINUX_TRY_COMPILE([ + #include + static void ctor(void *foo) + { + // fake ctor + } + ],[ + struct kmem_cache *skc_linux_cache; + const char *name = "test"; + size_t size = 4096; + size_t align = 8; + unsigned long flags = 0; + size_t useroffset = 0; + size_t usersize = size - useroffset; + + skc_linux_cache = kmem_cache_create_usercopy( + name, size, align, flags, useroffset, usersize, ctor); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_KMEM_CACHE_CREATE_USERCOPY, 1, + [kmem_cache_create_usercopy() exists]) + ],[ + AC_MSG_RESULT(no) + ]) + EXTRA_KCFLAGS="$tmp_flags" +]) diff --git a/module/spl/spl-kmem-cache.c b/module/spl/spl-kmem-cache.c index 99967b14f..45576b976 100644 --- a/module/spl/spl-kmem-cache.c +++ b/module/spl/spl-kmem-cache.c @@ -1001,8 +1001,17 @@ spl_kmem_cache_create(char *name, size_t size, size_t align, slabflags |= SLAB_USERCOPY; #endif - skc->skc_linux_cache = kmem_cache_create( - skc->skc_name, size, align, slabflags, NULL); +#if defined(HAVE_KMEM_CACHE_CREATE_USERCOPY) + /* + * Newer grsec patchset uses kmem_cache_create_usercopy() + * instead of SLAB_USERCOPY flag + */ + skc->skc_linux_cache = kmem_cache_create_usercopy( + skc->skc_name, size, align, slabflags, 0, size, NULL); +#else + skc->skc_linux_cache = kmem_cache_create( + skc->skc_name, size, align, slabflags, NULL); +#endif if (skc->skc_linux_cache == NULL) { rc = ENOMEM; goto out; -- cgit v1.2.3