Skip to content

Commit

Permalink
security: new security_inode_init_security API adds function callback
Browse files Browse the repository at this point in the history
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: Mimi Zohar <zohar@us.ibm.com>

Conflicts:
	fs/xfs/linux-2.6/xfs_iops.c

Change-Id: Ia84bb9f625e42ed17449c26fc25c26098979ec80
Signed-off-by: franciscofranco <franciscofranco.1990@gmail.com>
  • Loading branch information
Mimi Zohar authored and franciscofranco committed Mar 12, 2015
1 parent 6a14ed6 commit 0164119
Show file tree
Hide file tree
Showing 13 changed files with 230 additions and 164 deletions.
50 changes: 25 additions & 25 deletions fs/btrfs/xattr.c
Expand Up @@ -383,36 +383,36 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
XATTR_REPLACE);
}

int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
struct inode *inode, struct inode *dir,
const struct qstr *qstr)
int btrfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
void *fs_info)
{
int err;
size_t len;
void *value;
char *suffix;
const struct xattr *xattr;
struct btrfs_trans_handle *trans = fs_info;
char *name;
int err = 0;

err = security_inode_init_security(inode, dir, qstr, &suffix, &value,
&len);
if (err) {
if (err == -EOPNOTSUPP)
return 0;
return err;
}

name = kmalloc(XATTR_SECURITY_PREFIX_LEN + strlen(suffix) + 1,
GFP_NOFS);
if (!name) {
err = -ENOMEM;
} else {
for (xattr = xattr_array; xattr->name != NULL; xattr++) {
name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
strlen(xattr->name) + 1, GFP_NOFS);
if (!name) {
err = -ENOMEM;
break;
}
strcpy(name, XATTR_SECURITY_PREFIX);
strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix);
err = __btrfs_setxattr(trans, inode, name, value, len, 0);
strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);
err = __btrfs_setxattr(trans, inode, name,
xattr->value, xattr->value_len, 0);
kfree(name);
if (err < 0)
break;
}

kfree(suffix);
kfree(value);
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);
}
34 changes: 18 additions & 16 deletions fs/ext2/xattr_security.c
Expand Up @@ -46,28 +46,30 @@ ext2_xattr_security_set(struct dentry *dentry, const char *name,
value, size, flags);
}

int
ext2_init_security(struct inode *inode, struct inode *dir,
const struct qstr *qstr)
int ext2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
void *fs_info)
{
int err;
size_t len;
void *value;
char *name;
const struct xattr *xattr;
int err = 0;

err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
if (err) {
if (err == -EOPNOTSUPP)
return 0;
return err;
for (xattr = xattr_array; xattr->name != NULL; xattr++) {
err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
xattr->name, xattr->value,
xattr->value_len, 0);
if (err < 0)
break;
}
err = ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY,
name, value, len, 0);
kfree(name);
kfree(value);
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 = {
.prefix = XATTR_SECURITY_PREFIX,
.list = ext2_xattr_security_list,
Expand Down
36 changes: 20 additions & 16 deletions fs/ext3/xattr_security.c
Expand Up @@ -48,28 +48,32 @@ ext3_xattr_security_set(struct dentry *dentry, const char *name,
name, value, size, flags);
}

int
ext3_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
const struct qstr *qstr)
int ext3_initxattrs(struct inode *inode, const struct xattr *xattr_array,
void *fs_info)
{
int err;
size_t len;
void *value;
char *name;
const struct xattr *xattr;
handle_t *handle = fs_info;
int err = 0;

err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
if (err) {
if (err == -EOPNOTSUPP)
return 0;
return err;
for (xattr = xattr_array; xattr->name != NULL; xattr++) {
err = ext3_xattr_set_handle(handle, inode,
EXT3_XATTR_INDEX_SECURITY,
xattr->name, xattr->value,
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;
}

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 = {
.prefix = XATTR_SECURITY_PREFIX,
.list = ext3_xattr_security_list,
Expand Down
36 changes: 20 additions & 16 deletions fs/ext4/xattr_security.c
Expand Up @@ -48,28 +48,32 @@ ext4_xattr_security_set(struct dentry *dentry, const char *name,
name, value, size, flags);
}

int
ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
const struct qstr *qstr)
int ext4_initxattrs(struct inode *inode, const struct xattr *xattr_array,
void *fs_info)
{
int err;
size_t len;
void *value;
char *name;
const struct xattr *xattr;
handle_t *handle = fs_info;
int err = 0;

err = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
if (err) {
if (err == -EOPNOTSUPP)
return 0;
return err;
for (xattr = xattr_array; xattr->name != NULL; xattr++) {
err = ext4_xattr_set_handle(handle, inode,
EXT4_XATTR_INDEX_SECURITY,
xattr->name, xattr->value,
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;
}

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 = {
.prefix = XATTR_SECURITY_PREFIX,
.list = ext4_xattr_security_list,
Expand Down
38 changes: 18 additions & 20 deletions fs/gfs2/inode.c
Expand Up @@ -624,31 +624,29 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
return error;
}

static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
const struct qstr *qstr)
int gfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
void *fs_info)
{
int err;
size_t len;
void *value;
char *name;

err = security_inode_init_security(&ip->i_inode, &dip->i_inode, qstr,
&name, &value, &len);

if (err) {
if (err == -EOPNOTSUPP)
return 0;
return err;
const struct xattr *xattr;
int err = 0;

for (xattr = xattr_array; xattr->name != NULL; xattr++) {
err = __gfs2_xattr_set(inode, xattr->name, xattr->value,
xattr->value_len, 0,
GFS2_EATYPE_SECURITY);
if (err < 0)
break;
}

err = __gfs2_xattr_set(&ip->i_inode, name, value, len, 0,
GFS2_EATYPE_SECURITY);
kfree(value);
kfree(name);

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
* @dir: The parent directory
Expand Down
35 changes: 19 additions & 16 deletions fs/jffs2/security.c
Expand Up @@ -22,26 +22,29 @@
#include <linux/security.h>
#include "nodelist.h"

/* ---- Initial Security Label Attachment -------------- */
int jffs2_init_security(struct inode *inode, struct inode *dir,
const struct qstr *qstr)
/* ---- Initial Security Label(s) Attachment callback --- */
int jffs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
void *fs_info)
{
int rc;
size_t len;
void *value;
char *name;
const struct xattr *xattr;
int err = 0;

rc = security_inode_init_security(inode, dir, qstr, &name, &value, &len);
if (rc) {
if (rc == -EOPNOTSUPP)
return 0;
return rc;
for (xattr = xattr_array; xattr->name != NULL; xattr++) {
err = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY,
xattr->name, xattr->value,
xattr->value_len, 0);
if (err < 0)
break;
}
rc = do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, value, len, 0);
return err;
}

kfree(name);
kfree(value);
return rc;
/* ---- Initial Security Label(s) Attachment ----------- */
int jffs2_init_security(struct inode *inode, struct inode *dir,
const struct qstr *qstr)
{
return security_inode_init_security(inode, dir, qstr,
&jffs2_initxattrs, NULL);
}

/* ---- XATTR Handler for "security.*" ----------------- */
Expand Down
57 changes: 28 additions & 29 deletions fs/jfs/xattr.c
Expand Up @@ -1089,38 +1089,37 @@ int jfs_removexattr(struct dentry *dentry, const char *name)
}

#ifdef CONFIG_JFS_SECURITY
int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir,
const struct qstr *qstr)
int jfs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
void *fs_info)
{
int rc;
size_t len;
void *value;
char *suffix;
const struct xattr *xattr;
tid_t *tid = fs_info;
char *name;

rc = security_inode_init_security(inode, dir, qstr, &suffix, &value,
&len);
if (rc) {
if (rc == -EOPNOTSUPP)
return 0;
return rc;
}
name = kmalloc(XATTR_SECURITY_PREFIX_LEN + 1 + strlen(suffix),
GFP_NOFS);
if (!name) {
rc = -ENOMEM;
goto kmalloc_failed;
int err = 0;

for (xattr = xattr_array; xattr->name != NULL; xattr++) {
name = kmalloc(XATTR_SECURITY_PREFIX_LEN +
strlen(xattr->name) + 1, GFP_NOFS);
if (!name) {
err = -ENOMEM;
break;
}
strcpy(name, XATTR_SECURITY_PREFIX);
strcpy(name + XATTR_SECURITY_PREFIX_LEN, xattr->name);

err = __jfs_setxattr(*tid, inode, name,
xattr->value, xattr->value_len, 0);
kfree(name);
if (err < 0)
break;
}
strcpy(name, XATTR_SECURITY_PREFIX);
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 err;
}

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

0 comments on commit 0164119

Please sign in to comment.