Skip to content

Commit

Permalink
Linux 3.2 compat, security_inode_init_security()
Browse files Browse the repository at this point in the history
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
  • Loading branch information
behlendorf committed Jan 12, 2012
1 parent 2932b6a commit 166dd49
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 3 deletions.
39 changes: 38 additions & 1 deletion config/kernel-security-inode-init.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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"
])
1 change: 1 addition & 0 deletions config/kernel.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
164 changes: 162 additions & 2 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
29 changes: 29 additions & 0 deletions module/zfs/zpl_xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions zfs_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit 166dd49

Please sign in to comment.