diff --git a/config/kernel-mod-param.m4 b/config/kernel-mod-param.m4 new file mode 100644 index 000000000..b72be684a --- /dev/null +++ b/config/kernel-mod-param.m4 @@ -0,0 +1,30 @@ +dnl # +dnl # Grsecurity kernel API change +dnl # constified parameters of module_param_call() methods +dnl # +AC_DEFUN([ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST], [ + AC_MSG_CHECKING([whether module_param_call() is hardened]) + ZFS_LINUX_TRY_COMPILE([ + #include + #include + + int param_get(char *b, const struct kernel_param *kp) + { + return (0); + } + + int param_set(const char *b, const struct kernel_param *kp) + { + return (0); + } + + module_param_call(p, param_set, param_get, NULL, 0644); + ],[ + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(MODULE_PARAM_CALL_CONST, 1, + [hardened module_param_call]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel.m4 b/config/kernel.m4 index d8964a7e1..798f3511b 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -101,6 +101,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ ZFS_AC_KERNEL_GENERIC_IO_ACCT ZFS_AC_KERNEL_FPU ZFS_AC_KERNEL_KUID_HELPERS + ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST AS_IF([test "$LINUX_OBJ" != "$LINUX"], [ KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ" diff --git a/include/linux/Makefile.am b/include/linux/Makefile.am index 30f726892..9da9c068c 100644 --- a/include/linux/Makefile.am +++ b/include/linux/Makefile.am @@ -7,7 +7,8 @@ KERNEL_H = \ $(top_srcdir)/include/linux/blkdev_compat.h \ $(top_srcdir)/include/linux/utsname_compat.h \ $(top_srcdir)/include/linux/kmap_compat.h \ - $(top_srcdir)/include/linux/simd_x86.h + $(top_srcdir)/include/linux/simd_x86.h \ + $(top_srcdir)/include/linux/mod_compat.h USER_H = diff --git a/include/linux/mod_compat.h b/include/linux/mod_compat.h new file mode 100644 index 000000000..32aea4471 --- /dev/null +++ b/include/linux/mod_compat.h @@ -0,0 +1,39 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (C) 2016 Gvozden Neskovic . + */ + +#ifndef _MOD_COMPAT_H +#define _MOD_COMPAT_H + +#include +#include + +/* Grsecurity kernel API change */ +#ifdef MODULE_PARAM_CALL_CONST +typedef const struct kernel_param zfs_kernel_param_t; +#else +typedef struct kernel_param zfs_kernel_param_t; +#endif + +#endif /* _MOD_COMPAT_H */ diff --git a/module/zcommon/zfs_fletcher.c b/module/zcommon/zfs_fletcher.c index 221e586d8..5436bae9a 100644 --- a/module/zcommon/zfs_fletcher.c +++ b/module/zcommon/zfs_fletcher.c @@ -653,9 +653,10 @@ fletcher_4_fini(void) } #if defined(_KERNEL) && defined(HAVE_SPL) +#include static int -fletcher_4_param_get(char *buffer, struct kernel_param *unused) +fletcher_4_param_get(char *buffer, zfs_kernel_param_t *unused) { const uint32_t impl = IMPL_READ(fletcher_4_impl_chosen); char *fmt; @@ -676,7 +677,7 @@ fletcher_4_param_get(char *buffer, struct kernel_param *unused) } static int -fletcher_4_param_set(const char *val, struct kernel_param *unused) +fletcher_4_param_set(const char *val, zfs_kernel_param_t *unused) { return (fletcher_4_impl_set(val)); } diff --git a/module/zfs/vdev_raidz_math.c b/module/zfs/vdev_raidz_math.c index 2e57480c9..df9dc9386 100644 --- a/module/zfs/vdev_raidz_math.c +++ b/module/zfs/vdev_raidz_math.c @@ -120,7 +120,6 @@ vdev_raidz_math_get_ops() ops = (raidz_impl_ops_t *) &vdev_raidz_scalar_impl; break; default: - ASSERT(raidz_math_initialized); ASSERT3U(impl, <, raidz_supp_impl_cnt); ASSERT3U(raidz_supp_impl_cnt, >, 0); ops = raidz_supp_impl[impl]; @@ -556,8 +555,8 @@ static const struct { * @val Name of raidz implementation to use * @param Unused. */ -static int -zfs_vdev_raidz_impl_set(const char *val, struct kernel_param *kp) +int +vdev_raidz_impl_set(const char *val) { int err = -EINVAL; char req_name[RAIDZ_IMPL_NAME_MAX]; @@ -605,17 +604,17 @@ zfs_vdev_raidz_impl_set(const char *val, struct kernel_param *kp) return (err); } -int -vdev_raidz_impl_set(const char *val) -{ - ASSERT(raidz_math_initialized); +#if defined(_KERNEL) && defined(HAVE_SPL) +#include - return (zfs_vdev_raidz_impl_set(val, NULL)); +static int +zfs_vdev_raidz_impl_set(const char *val, zfs_kernel_param_t *kp) +{ + return (vdev_raidz_impl_set(val)); } -#if defined(_KERNEL) && defined(HAVE_SPL) static int -zfs_vdev_raidz_impl_get(char *buffer, struct kernel_param *kp) +zfs_vdev_raidz_impl_get(char *buffer, zfs_kernel_param_t *kp) { int i, cnt = 0; char *fmt;