]> granicus.if.org Git - zfs/commitdiff
Linux 3.2 compat, security_inode_init_security()
authorBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 12 Jan 2012 21:59:44 +0000 (13:59 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 12 Jan 2012 23:06:39 +0000 (15:06 -0800)
The security_inode_init_security() API has been changed to include
a filesystem specific callback to write security extended attributes.
This was done to support the initialization of multiple LSM xattrs
and the EVM xattr.

This change updates the code to use the new API when it's available.
Otherwise it falls back to the previous implementation.

In addition, the ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY
autoconf test has been made more rigerous by passing the expected
types.  This is done to ensure we always properly the detect the
correct form for the security_inode_init_security() API.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #516

config/kernel-security-inode-init.m4
config/kernel.m4
configure
module/zfs/zpl_xattr.c
zfs_config.h.in

index a26de9fd6b5d285c5286f3f1a3f6678538d23e14..c21588af75681f8778c15950b10bb796ef7436d5 100644 (file)
@@ -12,7 +12,14 @@ AC_DEFUN([ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY], [
        ZFS_LINUX_TRY_COMPILE([
                #include <linux/security.h>
        ],[
-               security_inode_init_security(NULL,NULL,NULL,NULL,NULL,NULL);
+               struct inode *ip __attribute__ ((unused)) = NULL;
+               struct inode *dip __attribute__ ((unused)) = NULL;
+               const struct qstr *str __attribute__ ((unused)) = NULL;
+               char *name __attribute__ ((unused)) = NULL;
+               void *value __attribute__ ((unused)) = NULL;
+               size_t len __attribute__ ((unused)) = 0;
+
+               security_inode_init_security(ip, dip, str, &name, &value, &len);
        ],[
                AC_MSG_RESULT(yes)
                AC_DEFINE(HAVE_6ARGS_SECURITY_INODE_INIT_SECURITY, 1,
@@ -22,3 +29,33 @@ AC_DEFUN([ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY], [
        ])
        EXTRA_KCFLAGS="$tmp_flags"
 ])
+
+dnl #
+dnl # 3.2 API change
+dnl # The security_inode_init_security() API has been changed to include
+dnl # a filesystem specific callback to write security extended attributes.
+dnl # This was done to support the initialization of multiple LSM xattrs
+dnl # and the EVM xattr.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY], [
+       AC_MSG_CHECKING([whether security_inode_init_security wants callback])
+       tmp_flags="$EXTRA_KCFLAGS"
+       EXTRA_KCFLAGS="-Werror"
+       ZFS_LINUX_TRY_COMPILE([
+               #include <linux/security.h>
+       ],[
+               struct inode *ip __attribute__ ((unused)) = NULL;
+               struct inode *dip __attribute__ ((unused)) = NULL;
+               const struct qstr *str __attribute__ ((unused)) = NULL;
+               initxattrs func __attribute__ ((unused)) = NULL;
+
+               security_inode_init_security(ip, dip, str, func, NULL);
+       ],[
+               AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY, 1,
+                         [security_inode_init_security wants callback])
+       ],[
+               AC_MSG_RESULT(no)
+       ])
+       EXTRA_KCFLAGS="$tmp_flags"
+])
index 2afe77e63b45c5fb6d2ab954608e3749d87d9b3d..45e9b149aa83296485625f918a60bbcf051dcdd0 100644 (file)
@@ -41,6 +41,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
        ZFS_AC_KERNEL_CHECK_DISK_SIZE_CHANGE
        ZFS_AC_KERNEL_TRUNCATE_SETSIZE
        ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY
+       ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY
        ZFS_AC_KERNEL_MOUNT_NODEV
        ZFS_AC_KERNEL_SHRINK
        ZFS_AC_KERNEL_BDI
index f30b1ffcbbf76a54e47b71783d495419e9a41308..510673810d8c316ee66bf9ee251c7429b3aaa539 100755 (executable)
--- a/configure
+++ b/configure
@@ -15144,7 +15144,14 @@ int
 main (void)
 {
 
-               security_inode_init_security(NULL,NULL,NULL,NULL,NULL,NULL);
+               struct inode *ip __attribute__ ((unused)) = NULL;
+               struct inode *dip __attribute__ ((unused)) = NULL;
+               const struct qstr *str __attribute__ ((unused)) = NULL;
+               char *name __attribute__ ((unused)) = NULL;
+               void *value __attribute__ ((unused)) = NULL;
+               size_t len __attribute__ ((unused)) = 0;
+
+               security_inode_init_security(ip, dip, str, &name, &value, &len);
 
   ;
   return 0;
@@ -15184,6 +15191,79 @@ $as_echo "no" >&6; }
 
 
 
+fi
+
+       rm -Rf build
+
+
+       EXTRA_KCFLAGS="$tmp_flags"
+
+
+       { $as_echo "$as_me:$LINENO: checking whether security_inode_init_security wants callback" >&5
+$as_echo_n "checking whether security_inode_init_security wants callback... " >&6; }
+       tmp_flags="$EXTRA_KCFLAGS"
+       EXTRA_KCFLAGS="-Werror"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+               #include <linux/security.h>
+
+int
+main (void)
+{
+
+               struct inode *ip __attribute__ ((unused)) = NULL;
+               struct inode *dip __attribute__ ((unused)) = NULL;
+               const struct qstr *str __attribute__ ((unused)) = NULL;
+               initxattrs func __attribute__ ((unused)) = NULL;
+
+               security_inode_init_security(ip, dip, str, func, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+       rm -Rf build && mkdir -p build
+       echo "obj-m := conftest.o" >build/Makefile
+       if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+               { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY 1
+_ACEOF
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+               { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
 fi
 
        rm -Rf build
@@ -20191,7 +20271,14 @@ int
 main (void)
 {
 
-               security_inode_init_security(NULL,NULL,NULL,NULL,NULL,NULL);
+               struct inode *ip __attribute__ ((unused)) = NULL;
+               struct inode *dip __attribute__ ((unused)) = NULL;
+               const struct qstr *str __attribute__ ((unused)) = NULL;
+               char *name __attribute__ ((unused)) = NULL;
+               void *value __attribute__ ((unused)) = NULL;
+               size_t len __attribute__ ((unused)) = 0;
+
+               security_inode_init_security(ip, dip, str, &name, &value, &len);
 
   ;
   return 0;
@@ -20231,6 +20318,79 @@ $as_echo "no" >&6; }
 
 
 
+fi
+
+       rm -Rf build
+
+
+       EXTRA_KCFLAGS="$tmp_flags"
+
+
+       { $as_echo "$as_me:$LINENO: checking whether security_inode_init_security wants callback" >&5
+$as_echo_n "checking whether security_inode_init_security wants callback... " >&6; }
+       tmp_flags="$EXTRA_KCFLAGS"
+       EXTRA_KCFLAGS="-Werror"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+               #include <linux/security.h>
+
+int
+main (void)
+{
+
+               struct inode *ip __attribute__ ((unused)) = NULL;
+               struct inode *dip __attribute__ ((unused)) = NULL;
+               const struct qstr *str __attribute__ ((unused)) = NULL;
+               initxattrs func __attribute__ ((unused)) = NULL;
+
+               security_inode_init_security(ip, dip, str, func, NULL);
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+       rm -Rf build && mkdir -p build
+       echo "obj-m := conftest.o" >build/Makefile
+       if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+               { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY 1
+_ACEOF
+
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+               { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
 fi
 
        rm -Rf build
index 9117b7bc14ccde96ed36ba84f9da2456c46dec90..51c81ed0c97d7003f2971aae979b75b6573c6ef2 100644 (file)
@@ -606,6 +606,34 @@ __zpl_xattr_security_set(struct inode *ip, const char *name,
 }
 ZPL_XATTR_SET_WRAPPER(zpl_xattr_security_set);
 
+#ifdef HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY
+static int
+__zpl_xattr_security_init(struct inode *ip, const struct xattr *xattrs,
+    void *fs_info)
+{
+       const struct xattr *xattr;
+       int error = 0;
+
+       for (xattr = xattrs; xattr->name != NULL; xattr++) {
+               error = __zpl_xattr_security_set(ip,
+                   xattr->name, xattr->value, xattr->value_len, 0);
+
+               if (error < 0)
+                       break;
+       }
+
+        return (error);
+}
+
+int
+zpl_xattr_security_init(struct inode *ip, struct inode *dip,
+    const struct qstr *qstr)
+{
+       return security_inode_init_security(ip, dip, qstr,
+           &__zpl_xattr_security_init, NULL);
+}
+
+#else
 int
 zpl_xattr_security_init(struct inode *ip, struct inode *dip,
     const struct qstr *qstr)
@@ -631,6 +659,7 @@ zpl_xattr_security_init(struct inode *ip, struct inode *dip,
 
         return (error);
 }
+#endif /* HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY */
 
 xattr_handler_t zpl_xattr_security_handler = {
        .prefix = XATTR_SECURITY_PREFIX,
index b53ca52d75a68337b033168b23052c0939f93442..4eee8929fa5028ad6f49c7f2d18338d159d6dcd6 100644 (file)
@@ -66,6 +66,9 @@
 /* blk_rq_sectors() is available */
 #undef HAVE_BLK_RQ_SECTORS
 
+/* security_inode_init_security wants callback */
+#undef HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY
+
 /* check_disk_size_change() is available */
 #undef HAVE_CHECK_DISK_SIZE_CHANGE