Skip to content

Commit 196f518

Browse files
eparistorvalds
authored andcommitted
IMA: explicit IMA i_flag to remove global lock on inode_delete
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 <eparis@redhat.com> Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 64c62f0 commit 196f518

File tree

3 files changed

+14
-5
lines changed

3 files changed

+14
-5
lines changed

include/linux/fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ struct inodes_stat_t {
235235
#define S_NOCMTIME 128 /* Do not update file c/mtime */
236236
#define S_SWAPFILE 256 /* Do not truncate: swapon got its bmaps */
237237
#define S_PRIVATE 512 /* Inode is fs-internal */
238+
#define S_IMA 1024 /* Inode has an associated IMA struct */
238239

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

273275
/* the read-only stuff doesn't really belong here, but any other place is
274276
probably as bad and I don't want to create yet another include file. */

security/integrity/ima/ima_iint.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ struct ima_iint_cache *ima_iint_find(struct inode *inode)
5959
{
6060
struct ima_iint_cache *iint;
6161

62+
if (!IS_IMA(inode))
63+
return NULL;
64+
6265
spin_lock(&ima_iint_lock);
6366
iint = __ima_iint_find(inode);
6467
spin_unlock(&ima_iint_lock);
@@ -91,6 +94,7 @@ int ima_inode_alloc(struct inode *inode)
9194
new_iint->inode = inode;
9295
new_node = &new_iint->rb_node;
9396

97+
mutex_lock(&inode->i_mutex); /* i_flags */
9498
spin_lock(&ima_iint_lock);
9599

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

114+
inode->i_flags |= S_IMA;
110115
rb_link_node(new_node, parent, p);
111116
rb_insert_color(new_node, &ima_iint_tree);
112117

113118
spin_unlock(&ima_iint_lock);
119+
mutex_unlock(&inode->i_mutex); /* i_flags */
114120

115121
return 0;
116122
out_err:
117123
spin_unlock(&ima_iint_lock);
124+
mutex_unlock(&inode->i_mutex); /* i_flags */
118125
iint_free(new_iint);
119126

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

136143
inode->i_readcount = 0;
137144

145+
if (!IS_IMA(inode))
146+
return;
147+
138148
spin_lock(&ima_iint_lock);
139149
iint = __ima_iint_find(inode);
140-
if (iint)
141-
rb_erase(&iint->rb_node, &ima_iint_tree);
150+
rb_erase(&iint->rb_node, &ima_iint_tree);
142151
spin_unlock(&ima_iint_lock);
143152

144-
if (!iint)
145-
return;
146-
147153
iint_free(iint);
148154
}
149155

security/integrity/ima/ima_main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ void ima_file_free(struct file *file)
211211

212212
if (!iint_initialized || !S_ISREG(inode->i_mode))
213213
return;
214+
214215
iint = ima_iint_find(inode);
215216

216217
if (iint)

0 commit comments

Comments
 (0)