Linux 3.2 compat, security_inode_init_security()
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
This commit is contained in:
parent
2932b6a800
commit
166dd49de0
|
@ -12,7 +12,14 @@ AC_DEFUN([ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY], [
|
||||||
ZFS_LINUX_TRY_COMPILE([
|
ZFS_LINUX_TRY_COMPILE([
|
||||||
#include <linux/security.h>
|
#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_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_6ARGS_SECURITY_INODE_INIT_SECURITY, 1,
|
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"
|
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"
|
||||||
|
])
|
||||||
|
|
|
@ -41,6 +41,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
|
||||||
ZFS_AC_KERNEL_CHECK_DISK_SIZE_CHANGE
|
ZFS_AC_KERNEL_CHECK_DISK_SIZE_CHANGE
|
||||||
ZFS_AC_KERNEL_TRUNCATE_SETSIZE
|
ZFS_AC_KERNEL_TRUNCATE_SETSIZE
|
||||||
ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY
|
ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY
|
||||||
|
ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY
|
||||||
ZFS_AC_KERNEL_MOUNT_NODEV
|
ZFS_AC_KERNEL_MOUNT_NODEV
|
||||||
ZFS_AC_KERNEL_SHRINK
|
ZFS_AC_KERNEL_SHRINK
|
||||||
ZFS_AC_KERNEL_BDI
|
ZFS_AC_KERNEL_BDI
|
||||||
|
|
|
@ -15144,7 +15144,14 @@ int
|
||||||
main (void)
|
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;
|
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
|
fi
|
||||||
|
|
||||||
rm -Rf build
|
rm -Rf build
|
||||||
|
@ -20191,7 +20271,14 @@ int
|
||||||
main (void)
|
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;
|
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
|
fi
|
||||||
|
|
||||||
rm -Rf build
|
rm -Rf build
|
||||||
|
|
|
@ -606,6 +606,34 @@ __zpl_xattr_security_set(struct inode *ip, const char *name,
|
||||||
}
|
}
|
||||||
ZPL_XATTR_SET_WRAPPER(zpl_xattr_security_set);
|
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
|
int
|
||||||
zpl_xattr_security_init(struct inode *ip, struct inode *dip,
|
zpl_xattr_security_init(struct inode *ip, struct inode *dip,
|
||||||
const struct qstr *qstr)
|
const struct qstr *qstr)
|
||||||
|
@ -631,6 +659,7 @@ zpl_xattr_security_init(struct inode *ip, struct inode *dip,
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
#endif /* HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY */
|
||||||
|
|
||||||
xattr_handler_t zpl_xattr_security_handler = {
|
xattr_handler_t zpl_xattr_security_handler = {
|
||||||
.prefix = XATTR_SECURITY_PREFIX,
|
.prefix = XATTR_SECURITY_PREFIX,
|
||||||
|
|
|
@ -66,6 +66,9 @@
|
||||||
/* blk_rq_sectors() is available */
|
/* blk_rq_sectors() is available */
|
||||||
#undef HAVE_BLK_RQ_SECTORS
|
#undef HAVE_BLK_RQ_SECTORS
|
||||||
|
|
||||||
|
/* security_inode_init_security wants callback */
|
||||||
|
#undef HAVE_CALLBACK_SECURITY_INODE_INIT_SECURITY
|
||||||
|
|
||||||
/* check_disk_size_change() is available */
|
/* check_disk_size_change() is available */
|
||||||
#undef HAVE_CHECK_DISK_SIZE_CHANGE
|
#undef HAVE_CHECK_DISK_SIZE_CHANGE
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue