提交 9d8f13ba 编写于 作者: M Mimi Zohar

security: new security_inode_init_security API adds function callback

This patch changes the security_inode_init_security API by adding a
filesystem specific callback to write security extended attributes.
This change is in preparation for supporting the initialization of
multiple LSM xattrs and the EVM xattr.  Initially the callback function
walks an array of xattrs, writing each xattr separately, but could be
optimized to write multiple xattrs at once.

For existing security_inode_init_security() calls, which have not yet
been converted to use the new callback function, such as those in
reiserfs and ocfs2, this patch defines security_old_inode_init_security().
Signed-off-by: NMimi Zohar <zohar@us.ibm.com>
上级 0f2a55d5
...@@ -360,36 +360,36 @@ int btrfs_removexattr(struct dentry *dentry, const char *name) ...@@ -360,36 +360,36 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
XATTR_REPLACE); XATTR_REPLACE);
} }
int btrfs_xattr_security_init(struct btrfs_trans_handle *trans, int btrfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
struct inode *inode, struct inode *dir, void *fs_info)
const struct qstr *qstr)
{ {
int err; const struct xattr *xattr;
size_t len; struct btrfs_trans_handle *trans = fs_info;
void *value;
char *suffix;
char *name; char *name;
int err = 0;
err = security_inode_init_security(inode, dir, qstr, &suffix, &value, for (xattr = xattr_array; xattr->name != NULL; xattr++) {
&len); name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
if (err) { strlen(xattr->name) + 1, GFP_NOFS);
if (err == -EOPNOTSUPP) if (!name) {
return 0; err = -ENOMEM;
return err; break;
} }
name = kmalloc(XATTR_SECURITY_PREFIX_LEN + strlen(suffix) + 1,
GFP_NOFS);
if (!name) {
err = -ENOMEM;
} else {
strcpy(name, XATTR_SECURITY_PREFIX); strcpy(name, XATTR_SECURITY_PREFIX);
strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
err = __btrfs_setxattr(trans, inode, name, value, len, 0); err = __btrfs_setxattr(trans, inode, name,
xattr->value, xattr->value_len, 0);
kfree(name); kfree(name);
if (err < 0)
break;
} }
kfree(suffix);
kfree(value);
return err; return err;
} }
int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
struct inode *inode, struct inode *dir,
const struct qstr *qstr)
{
return security_inode_init_security(inode, dir, qstr,
&btrfs_initxattrs, trans);
}
...@@ -46,28 +46,30 @@ ext2_xattr_security_set(struct dentry *dentry, const char *name, ...@@ -46,28 +46,30 @@ ext2_xattr_security_set(struct dentry *dentry, const char *name,
value, size, flags); value, size, flags);
} }
int int ext2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
ext2_init_security(struct inode *inode, struct inode *dir, void *fs_info)
const struct qstr *qstr)
{ {
int err; const struct xattr *xattr;
size_t len; int err = 0;
void *value;
char *name;
err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); for (xattr = xattr_array; xattr->name != NULL; xattr++) {
if (err) { err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
if (err == -EOPNOTSUPP) xattr->name, xattr->value,
return 0; xattr->value_len, 0);
return err; if (err < 0)
break;
} }
err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
name, value, len, 0);
kfree(name);
kfree(value);
return err; return err;
} }
int
ext2_init_security(struct inode *inode, struct inode *dir,
const struct qstr *qstr)
{
return security_inode_init_security(inode, dir, qstr,
&ext2_initxattrs, NULL);
}
const struct xattr_handler ext2_xattr_security_handler = { const struct xattr_handler ext2_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.list = ext2_xattr_security_list, .list = ext2_xattr_security_list,
......
...@@ -48,28 +48,32 @@ ext3_xattr_security_set(struct dentry *dentry, const char *name, ...@@ -48,28 +48,32 @@ ext3_xattr_security_set(struct dentry *dentry, const char *name,
name, value, size, flags); name, value, size, flags);
} }
int int ext3_initxattrs(struct inode *inode, const struct xattr *xattr_array,
ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir, void *fs_info)
const struct qstr *qstr)
{ {
int err; const struct xattr *xattr;
size_t len; handle_t *handle = fs_info;
void *value; int err = 0;
char *name;
err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); for (xattr = xattr_array; xattr->name != NULL; xattr++) {
if (err) { err = ext3_xattr_set_handle(handle, inode,
if (err == -EOPNOTSUPP) EXT3_XATTR_INDEX_SECURITY,
return 0; xattr->name, xattr->value,
return err; xattr->value_len, 0);
if (err < 0)
break;
} }
err = ext3_xattr_set_handle(handle, inode, EXT3_XATTR_INDEX_SECURITY,
name, value, len, 0);
kfree(name);
kfree(value);
return err; return err;
} }
int
ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
const struct qstr *qstr)
{
return security_inode_init_security(inode, dir, qstr,
&ext3_initxattrs, handle);
}
const struct xattr_handler ext3_xattr_security_handler = { const struct xattr_handler ext3_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.list = ext3_xattr_security_list, .list = ext3_xattr_security_list,
......
...@@ -48,28 +48,32 @@ ext4_xattr_security_set(struct dentry *dentry, const char *name, ...@@ -48,28 +48,32 @@ ext4_xattr_security_set(struct dentry *dentry, const char *name,
name, value, size, flags); name, value, size, flags);
} }
int int ext4_initxattrs(struct inode *inode, const struct xattr *xattr_array,
ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir, void *fs_info)
const struct qstr *qstr)
{ {
int err; const struct xattr *xattr;
size_t len; handle_t *handle = fs_info;
void *value; int err = 0;
char *name;
err = security_inode_init_security(inode, dir, qstr, &name, &value, &len); for (xattr = xattr_array; xattr->name != NULL; xattr++) {
if (err) { err = ext4_xattr_set_handle(handle, inode,
if (err == -EOPNOTSUPP) EXT4_XATTR_INDEX_SECURITY,
return 0; xattr->name, xattr->value,
return err; xattr->value_len, 0);
if (err < 0)
break;
} }
err = ext4_xattr_set_handle(handle, inode, EXT4_XATTR_INDEX_SECURITY,
name, value, len, 0);
kfree(name);
kfree(value);
return err; return err;
} }
int
ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
const struct qstr *qstr)
{
return security_inode_init_security(inode, dir, qstr,
&ext4_initxattrs, handle);
}
const struct xattr_handler ext4_xattr_security_handler = { const struct xattr_handler ext4_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX, .prefix = XATTR_SECURITY_PREFIX,
.list = ext4_xattr_security_list, .list = ext4_xattr_security_list,
......
...@@ -624,31 +624,29 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, ...@@ -624,31 +624,29 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
return error; return error;
} }
static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip, int gfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
const struct qstr *qstr) void *fs_info)
{ {
int err; const struct xattr *xattr;
size_t len; int err = 0;
void *value;
char *name; for (xattr = xattr_array; xattr->name != NULL; xattr++) {
err = __gfs2_xattr_set(inode, xattr->name, xattr->value,
err = security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr, xattr->value_len, 0,
&name, &value, &len); GFS2_EATYPE_SECURITY);
if (err < 0)
if (err) { break;
if (err == -EOPNOTSUPP)
return 0;
return err;
} }
err = __gfs2_xattr_set(&ip->i_inode, name, value, len, 0,
GFS2_EATYPE_SECURITY);
kfree(value);
kfree(name);
return err; return err;
} }
static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
const struct qstr *qstr)
{
return security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr,
&gfs2_initxattrs, NULL);
}
/** /**
* gfs2_create_inode - Create a new inode * gfs2_create_inode - Create a new inode
* @dir: The parent directory * @dir: The parent directory
......
...@@ -22,26 +22,29 @@ ...@@ -22,26 +22,29 @@
#include <linux/security.h> #include <linux/security.h>
#include "nodelist.h" #include "nodelist.h"
/* ---- Initial Security Label Attachment -------------- */ /* ---- Initial Security Label(s) Attachment callback --- */
int jffs2_init_security(struct inode *inode, struct inode *dir, int jffs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
const struct qstr *qstr) void *fs_info)
{ {
int rc; const struct xattr *xattr;
size_t len; int err = 0;
void *value;
char *name;
rc = security_inode_init_security(inode, dir, qstr, &name, &value, &len); for (xattr = xattr_array; xattr->name != NULL; xattr++) {
if (rc) { err = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY,
if (rc == -EOPNOTSUPP) xattr->name, xattr->value,
return 0; xattr->value_len, 0);
return rc; if (err < 0)
break;
} }
rc = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, value, len, 0); return err;
}
kfree(name); /* ---- Initial Security Label(s) Attachment ----------- */
kfree(value); int jffs2_init_security(struct inode *inode, struct inode *dir,
return rc; const struct qstr *qstr)
{
return security_inode_init_security(inode, dir, qstr,
&jffs2_initxattrs, NULL);
} }
/* ---- XATTR Handler for "security.*" ----------------- */ /* ---- XATTR Handler for "security.*" ----------------- */
......
...@@ -1091,38 +1091,37 @@ int jfs_removexattr(struct dentry *dentry, const char *name) ...@@ -1091,38 +1091,37 @@ int jfs_removexattr(struct dentry *dentry, const char *name)
} }
#ifdef CONFIG_JFS_SECURITY #ifdef CONFIG_JFS_SECURITY
int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir, int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
const struct qstr *qstr) void *fs_info)
{ {
int rc; const struct xattr *xattr;
size_t len; tid_t *tid = fs_info;
void *value;
char *suffix;
char *name; char *name;
int err = 0;
rc = security_inode_init_security(inode, dir, qstr, &suffix, &value,
&len); for (xattr = xattr_array; xattr->name != NULL; xattr++) {
if (rc) { name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
if (rc == -EOPNOTSUPP) strlen(xattr->name) + 1, GFP_NOFS);
return 0; if (!name) {
return rc; err = -ENOMEM;
} break;
name = kmalloc(XATTR_SECURITY_PREFIX_LEN + 1 + strlen(suffix), }
GFP_NOFS); strcpy(name, XATTR_SECURITY_PREFIX);
if (!name) { strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
rc = -ENOMEM;
goto kmalloc_failed; err = __jfs_setxattr(*tid, inode, name,
xattr->value, xattr->value_len, 0);
kfree(name);
if (err < 0)
break;
} }
strcpy(name, XATTR_SECURITY_PREFIX); return err;
strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); }
rc = __jfs_setxattr(tid, inode, name, value, len, 0);
kfree(name);
kmalloc_failed:
kfree(suffix);
kfree(value);
return rc; int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir,
const struct qstr *qstr)
{
return security_inode_init_security(inode, dir, qstr,
&jfs_initxattrs, &tid);
} }
#endif #endif
...@@ -7185,20 +7185,9 @@ int ocfs2_init_security_and_acl(struct inode *dir, ...@@ -7185,20 +7185,9 @@ int ocfs2_init_security_and_acl(struct inode *dir,
{ {
int ret = 0; int ret = 0;
struct buffer_head *dir_bh = NULL; struct buffer_head *dir_bh = NULL;
struct ocfs2_security_xattr_info si = {
.enable = 1,
};
ret = ocfs2_init_security_get(inode, dir, qstr, &si); ret = ocfs2_init_security_get(inode, dir, qstr, NULL);
if (!ret) { if (!ret) {
ret = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
si.name, si.value, si.value_len,
XATTR_CREATE);
if (ret) {
mlog_errno(ret);
goto leave;
}
} else if (ret != -EOPNOTSUPP) {
mlog_errno(ret); mlog_errno(ret);
goto leave; goto leave;
} }
...@@ -7255,6 +7244,22 @@ static int ocfs2_xattr_security_set(struct dentry *dentry, const char *name, ...@@ -7255,6 +7244,22 @@ static int ocfs2_xattr_security_set(struct dentry *dentry, const char *name,
name, value, size, flags); name, value, size, flags);
} }
int ocfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
void *fs_info)
{
const struct xattr *xattr;
int err = 0;
for (xattr = xattr_array; xattr->name != NULL; xattr++) {
err = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
xattr->name, xattr->value,
xattr->value_len, XATTR_CREATE);
if (err)
break;
}
return err;
}
int ocfs2_init_security_get(struct inode *inode, int ocfs2_init_security_get(struct inode *inode,
struct inode *dir, struct inode *dir,
const struct qstr *qstr, const struct qstr *qstr,
...@@ -7263,8 +7268,13 @@ int ocfs2_init_security_get(struct inode *inode, ...@@ -7263,8 +7268,13 @@ int ocfs2_init_security_get(struct inode *inode,
/* check whether ocfs2 support feature xattr */ /* check whether ocfs2 support feature xattr */
if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb))) if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb)))
return -EOPNOTSUPP; return -EOPNOTSUPP;
return security_inode_init_security(inode, dir, qstr, &si->name, if (si)
&si->value, &si->value_len); return security_old_inode_init_security(inode, dir, qstr,
&si->name, &si->value,
&si->value_len);
return security_inode_init_security(inode, dir, qstr,
&ocfs2_initxattrs, NULL);
} }
int ocfs2_init_security_set(handle_t *handle, int ocfs2_init_security_set(handle_t *handle,
......
...@@ -66,8 +66,8 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode, ...@@ -66,8 +66,8 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode,
if (IS_PRIVATE(dir)) if (IS_PRIVATE(dir))
return 0; return 0;
error = security_inode_init_security(inode, dir, qstr, &sec->name, error = security_old_inode_init_security(inode, dir, qstr, &sec->name,
&sec->value, &sec->length); &sec->value, &sec->length);
if (error) { if (error) {
if (error == -EOPNOTSUPP) if (error == -EOPNOTSUPP)
error = 0; error = 0;
......
...@@ -93,37 +93,38 @@ xfs_mark_inode_dirty( ...@@ -93,37 +93,38 @@ xfs_mark_inode_dirty(
mark_inode_dirty(inode); mark_inode_dirty(inode);
} }
int xfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
void *fs_info)
{
const struct xattr *xattr;
struct xfs_inode *ip = XFS_I(inode);
int error = 0;
for (xattr = xattr_array; xattr->name != NULL; xattr++) {
error = xfs_attr_set(ip, xattr->name, xattr->value,
xattr->value_len, ATTR_SECURE);
if (error < 0)
break;
}
return error;
}
/* /*
* Hook in SELinux. This is not quite correct yet, what we really need * Hook in SELinux. This is not quite correct yet, what we really need
* here (as we do for default ACLs) is a mechanism by which creation of * here (as we do for default ACLs) is a mechanism by which creation of
* these attrs can be journalled at inode creation time (along with the * these attrs can be journalled at inode creation time (along with the
* inode, of course, such that log replay can't cause these to be lost). * inode, of course, such that log replay can't cause these to be lost).
*/ */
STATIC int STATIC int
xfs_init_security( xfs_init_security(
struct inode *inode, struct inode *inode,
struct inode *dir, struct inode *dir,
const struct qstr *qstr) const struct qstr *qstr)
{ {
struct xfs_inode *ip = XFS_I(inode); return security_inode_init_security(inode, dir, qstr,
size_t length; &xfs_initxattrs, NULL);
void *value;
unsigned char *name;
int error;
error = security_inode_init_security(inode, dir, qstr, (char **)&name,
&value, &length);
if (error) {
if (error == -EOPNOTSUPP)
return 0;
return -error;
}
error = xfs_attr_set(ip, name, value, length, ATTR_SECURE);
kfree(name);
kfree(value);
return error;
} }
static void static void
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/key.h> #include <linux/key.h>
#include <linux/xfrm.h> #include <linux/xfrm.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/xattr.h>
#include <net/flow.h> #include <net/flow.h>
/* Maximum number of letters for an LSM name string */ /* Maximum number of letters for an LSM name string */
...@@ -147,6 +148,10 @@ extern int mmap_min_addr_handler(struct ctl_table *table, int write, ...@@ -147,6 +148,10 @@ extern int mmap_min_addr_handler(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos); void __user *buffer, size_t *lenp, loff_t *ppos);
#endif #endif
/* security_inode_init_security callback function to write xattrs */
typedef int (*initxattrs) (struct inode *inode,
const struct xattr *xattr_array, void *fs_data);
#ifdef CONFIG_SECURITY #ifdef CONFIG_SECURITY
struct security_mnt_opts { struct security_mnt_opts {
...@@ -1704,8 +1709,11 @@ int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts); ...@@ -1704,8 +1709,11 @@ int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
int security_inode_alloc(struct inode *inode); int security_inode_alloc(struct inode *inode);
void security_inode_free(struct inode *inode); void security_inode_free(struct inode *inode);
int security_inode_init_security(struct inode *inode, struct inode *dir, int security_inode_init_security(struct inode *inode, struct inode *dir,
const struct qstr *qstr, char **name, const struct qstr *qstr,
void **value, size_t *len); initxattrs initxattrs, void *fs_data);
int security_old_inode_init_security(struct inode *inode, struct inode *dir,
const struct qstr *qstr, char **name,
void **value, size_t *len);
int security_inode_create(struct inode *dir, struct dentry *dentry, int mode); int security_inode_create(struct inode *dir, struct dentry *dentry, int mode);
int security_inode_link(struct dentry *old_dentry, struct inode *dir, int security_inode_link(struct dentry *old_dentry, struct inode *dir,
struct dentry *new_dentry); struct dentry *new_dentry);
...@@ -2035,9 +2043,8 @@ static inline void security_inode_free(struct inode *inode) ...@@ -2035,9 +2043,8 @@ static inline void security_inode_free(struct inode *inode)
static inline int security_inode_init_security(struct inode *inode, static inline int security_inode_init_security(struct inode *inode,
struct inode *dir, struct inode *dir,
const struct qstr *qstr, const struct qstr *qstr,
char **name, initxattrs initxattrs,
void **value, void *fs_data)
size_t *len)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
......
...@@ -67,6 +67,12 @@ struct xattr_handler { ...@@ -67,6 +67,12 @@ struct xattr_handler {
size_t size, int flags, int handler_flags); size_t size, int flags, int handler_flags);
}; };
struct xattr {
char *name;
void *value;
size_t value_len;
};
ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t); ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t); ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
......
...@@ -1878,7 +1878,7 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) ...@@ -1878,7 +1878,7 @@ shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE); inode = shmem_get_inode(dir->i_sb, dir, mode, dev, VM_NORESERVE);
if (inode) { if (inode) {
error = security_inode_init_security(inode, dir, error = security_inode_init_security(inode, dir,
&dentry->d_name, NULL, &dentry->d_name,
NULL, NULL); NULL, NULL);
if (error) { if (error) {
if (error != -EOPNOTSUPP) { if (error != -EOPNOTSUPP) {
...@@ -2018,7 +2018,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s ...@@ -2018,7 +2018,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
if (!inode) if (!inode)
return -ENOSPC; return -ENOSPC;
error = security_inode_init_security(inode, dir, &dentry->d_name, NULL, error = security_inode_init_security(inode, dir, &dentry->d_name,
NULL, NULL); NULL, NULL);
if (error) { if (error) {
if (error != -EOPNOTSUPP) { if (error != -EOPNOTSUPP) {
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#include <linux/security.h> #include <linux/security.h>
#include <linux/ima.h> #include <linux/ima.h>
#define MAX_LSM_XATTR 1
/* Boot-time LSM user choice */ /* Boot-time LSM user choice */
static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
CONFIG_DEFAULT_SECURITY; CONFIG_DEFAULT_SECURITY;
...@@ -339,15 +341,46 @@ void security_inode_free(struct inode *inode) ...@@ -339,15 +341,46 @@ void security_inode_free(struct inode *inode)
} }
int security_inode_init_security(struct inode *inode, struct inode *dir, int security_inode_init_security(struct inode *inode, struct inode *dir,
const struct qstr *qstr, char **name, const struct qstr *qstr,
void **value, size_t *len) const initxattrs initxattrs, void *fs_data)
{
struct xattr new_xattrs[MAX_LSM_XATTR + 1];
struct xattr *lsm_xattr;
int ret;
if (unlikely(IS_PRIVATE(inode)))
return -EOPNOTSUPP;
memset(new_xattrs, 0, sizeof new_xattrs);
if (!initxattrs)
return security_ops->inode_init_security(inode, dir, qstr,
NULL, NULL, NULL);
lsm_xattr = new_xattrs;
ret = security_ops->inode_init_security(inode, dir, qstr,
&lsm_xattr->name,
&lsm_xattr->value,
&lsm_xattr->value_len);
if (ret)
goto out;
ret = initxattrs(inode, new_xattrs, fs_data);
out:
kfree(lsm_xattr->name);
kfree(lsm_xattr->value);
return (ret == -EOPNOTSUPP) ? 0 : ret;
}
EXPORT_SYMBOL(security_inode_init_security);
int security_old_inode_init_security(struct inode *inode, struct inode *dir,
const struct qstr *qstr, char **name,
void **value, size_t *len)
{ {
if (unlikely(IS_PRIVATE(inode))) if (unlikely(IS_PRIVATE(inode)))
return -EOPNOTSUPP; return -EOPNOTSUPP;
return security_ops->inode_init_security(inode, dir, qstr, name, value, return security_ops->inode_init_security(inode, dir, qstr, name, value,
len); len);
} }
EXPORT_SYMBOL(security_inode_init_security); EXPORT_SYMBOL(security_old_inode_init_security);
#ifdef CONFIG_SECURITY_PATH #ifdef CONFIG_SECURITY_PATH
int security_path_mknod(struct path *dir, struct dentry *dentry, int mode, int security_path_mknod(struct path *dir, struct dentry *dentry, int mode,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册