diff options
author | Kevin Tanguy <[email protected]> | 2017-01-17 21:05:14 +0100 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2017-01-17 12:05:14 -0800 |
commit | 0194e4a03c394f0bb85cba78ac12f10c480c5670 (patch) | |
tree | 4b509fbbf9de775820f4b338ae4ebafbaed38888 | |
parent | 120faefed90aa4c276a3db45525dc5c804cb1a00 (diff) |
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 <rageltman@sempervictus>
Reviewed-by: spendergrsec <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Kevin Tanguy <[email protected]>
Closes #595
-rw-r--r-- | config/spl-build.m4 | 37 | ||||
-rw-r--r-- | 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 <linux/slab.h> + 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; |