Skip to content

Commit

Permalink
IMA: explicit IMA i_flag to remove global lock on inode_delete
Browse files Browse the repository at this point in the history
Currently for every removed inode IMA must take a global lock and search
the IMA rbtree looking for an associated integrity structure.  Instead
we explicitly mark an inode when we add an integrity structure so we
only have to take the global lock and do the removal if it exists.

Signed-off-by: Eric Paris <[email protected]>
Acked-by: Mimi Zohar <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
eparis authored and torvalds committed Oct 26, 2010
1 parent 64c62f0 commit 196f518
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 5 deletions.
2 changes: 2 additions & 0 deletions include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ struct inodes_stat_t {
#define S_NOCMTIME 128 /* Do not update file c/mtime */
#define S_SWAPFILE 256 /* Do not truncate: swapon got its bmaps */
#define S_PRIVATE 512 /* Inode is fs-internal */
#define S_IMA 1024 /* Inode has an associated IMA struct */

/*
* Note that nosuid etc flags are inode-specific: setting some file-system
Expand Down Expand Up @@ -269,6 +270,7 @@ struct inodes_stat_t {
#define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME)
#define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE)
#define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE)
#define IS_IMA(inode) ((inode)->i_flags & S_IMA)

/* the read-only stuff doesn't really belong here, but any other place is
probably as bad and I don't want to create yet another include file. */
Expand Down
16 changes: 11 additions & 5 deletions security/integrity/ima/ima_iint.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ struct ima_iint_cache *ima_iint_find(struct inode *inode)
{
struct ima_iint_cache *iint;

if (!IS_IMA(inode))
return NULL;

spin_lock(&ima_iint_lock);
iint = __ima_iint_find(inode);
spin_unlock(&ima_iint_lock);
Expand Down Expand Up @@ -91,6 +94,7 @@ int ima_inode_alloc(struct inode *inode)
new_iint->inode = inode;
new_node = &new_iint->rb_node;

mutex_lock(&inode->i_mutex); /* i_flags */
spin_lock(&ima_iint_lock);

p = &ima_iint_tree.rb_node;
Expand All @@ -107,14 +111,17 @@ int ima_inode_alloc(struct inode *inode)
goto out_err;
}

inode->i_flags |= S_IMA;
rb_link_node(new_node, parent, p);
rb_insert_color(new_node, &ima_iint_tree);

spin_unlock(&ima_iint_lock);
mutex_unlock(&inode->i_mutex); /* i_flags */

return 0;
out_err:
spin_unlock(&ima_iint_lock);
mutex_unlock(&inode->i_mutex); /* i_flags */
iint_free(new_iint);

return rc;
Expand All @@ -135,15 +142,14 @@ void ima_inode_free(struct inode *inode)

inode->i_readcount = 0;

if (!IS_IMA(inode))
return;

spin_lock(&ima_iint_lock);
iint = __ima_iint_find(inode);
if (iint)
rb_erase(&iint->rb_node, &ima_iint_tree);
rb_erase(&iint->rb_node, &ima_iint_tree);
spin_unlock(&ima_iint_lock);

if (!iint)
return;

iint_free(iint);
}

Expand Down
1 change: 1 addition & 0 deletions security/integrity/ima/ima_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ void ima_file_free(struct file *file)

if (!iint_initialized || !S_ISREG(inode->i_mode))
return;

iint = ima_iint_find(inode);

if (iint)
Expand Down

0 comments on commit 196f518

Please sign in to comment.