diff options
-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; |