Skip to content

Commit e044374

Browse files
amir73ilmimizohar
authored andcommitted
ima: annotate iint mutex to avoid lockdep false positive warnings
It is not clear that IMA should be nested at all, but as long is it measures files both on overlayfs and on underlying fs, we need to annotate the iint mutex to avoid lockdep false positives related to IMA + overlayfs, same as overlayfs annotates the inode mutex. Reported-and-tested-by: [email protected] Signed-off-by: Amir Goldstein <[email protected]> Cc: [email protected] Signed-off-by: Mimi Zohar <[email protected]>
1 parent 94f6f05 commit e044374

File tree

1 file changed

+37
-11
lines changed

1 file changed

+37
-11
lines changed

security/integrity/iint.c

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,32 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode)
6666
return iint;
6767
}
6868

69-
static void iint_free(struct integrity_iint_cache *iint)
69+
#define IMA_MAX_NESTING (FILESYSTEM_MAX_STACK_DEPTH+1)
70+
71+
/*
72+
* It is not clear that IMA should be nested at all, but as long is it measures
73+
* files both on overlayfs and on underlying fs, we need to annotate the iint
74+
* mutex to avoid lockdep false positives related to IMA + overlayfs.
75+
* See ovl_lockdep_annotate_inode_mutex_key() for more details.
76+
*/
77+
static inline void iint_lockdep_annotate(struct integrity_iint_cache *iint,
78+
struct inode *inode)
79+
{
80+
#ifdef CONFIG_LOCKDEP
81+
static struct lock_class_key iint_mutex_key[IMA_MAX_NESTING];
82+
83+
int depth = inode->i_sb->s_stack_depth;
84+
85+
if (WARN_ON_ONCE(depth < 0 || depth >= IMA_MAX_NESTING))
86+
depth = 0;
87+
88+
lockdep_set_class(&iint->mutex, &iint_mutex_key[depth]);
89+
#endif
90+
}
91+
92+
static void iint_init_always(struct integrity_iint_cache *iint,
93+
struct inode *inode)
7094
{
71-
kfree(iint->ima_hash);
7295
iint->ima_hash = NULL;
7396
iint->version = 0;
7497
iint->flags = 0UL;
@@ -80,6 +103,14 @@ static void iint_free(struct integrity_iint_cache *iint)
80103
iint->ima_creds_status = INTEGRITY_UNKNOWN;
81104
iint->evm_status = INTEGRITY_UNKNOWN;
82105
iint->measured_pcrs = 0;
106+
mutex_init(&iint->mutex);
107+
iint_lockdep_annotate(iint, inode);
108+
}
109+
110+
static void iint_free(struct integrity_iint_cache *iint)
111+
{
112+
kfree(iint->ima_hash);
113+
mutex_destroy(&iint->mutex);
83114
kmem_cache_free(iint_cache, iint);
84115
}
85116

@@ -104,6 +135,8 @@ struct integrity_iint_cache *integrity_inode_get(struct inode *inode)
104135
if (!iint)
105136
return NULL;
106137

138+
iint_init_always(iint, inode);
139+
107140
write_lock(&integrity_iint_lock);
108141

109142
p = &integrity_iint_tree.rb_node;
@@ -153,25 +186,18 @@ void integrity_inode_free(struct inode *inode)
153186
iint_free(iint);
154187
}
155188

156-
static void init_once(void *foo)
189+
static void iint_init_once(void *foo)
157190
{
158191
struct integrity_iint_cache *iint = (struct integrity_iint_cache *) foo;
159192

160193
memset(iint, 0, sizeof(*iint));
161-
iint->ima_file_status = INTEGRITY_UNKNOWN;
162-
iint->ima_mmap_status = INTEGRITY_UNKNOWN;
163-
iint->ima_bprm_status = INTEGRITY_UNKNOWN;
164-
iint->ima_read_status = INTEGRITY_UNKNOWN;
165-
iint->ima_creds_status = INTEGRITY_UNKNOWN;
166-
iint->evm_status = INTEGRITY_UNKNOWN;
167-
mutex_init(&iint->mutex);
168194
}
169195

170196
static int __init integrity_iintcache_init(void)
171197
{
172198
iint_cache =
173199
kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache),
174-
0, SLAB_PANIC, init_once);
200+
0, SLAB_PANIC, iint_init_once);
175201
return 0;
176202
}
177203
DEFINE_LSM(integrity) = {

0 commit comments

Comments
 (0)