Skip to content

Commit 39b755d

Browse files
author
Aaron Brookner
committed
ima: annotate iint mutex to avoid lockdep false positive warnings
JIRA: https://issues.redhat.com/browse/RHEL-59837 (cherry picked from commit e044374) 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: syzbot+b42fe626038981fb7bfa@syzkaller.appspotmail.com Signed-off-by: Amir Goldstein <amir73il@gmail.com> Cc: stable@vger.kernel.org Signed-off-by: Mimi Zohar <zohar@linux.ibm.com> Signed-off-by: Aaron Brookner <abrookne@redhat.com>
1 parent 7dc962d commit 39b755d

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
@@ -68,9 +68,32 @@ struct integrity_iint_cache *integrity_iint_find(struct inode *inode)
6868
return iint;
6969
}
7070

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

@@ -114,6 +145,8 @@ struct integrity_iint_cache *integrity_inode_get(struct inode *inode)
114145
if (!iint)
115146
return NULL;
116147

148+
iint_init_always(iint, inode);
149+
117150
write_lock(&integrity_iint_lock);
118151

119152
p = &integrity_iint_tree.rb_node;
@@ -158,25 +191,18 @@ void integrity_inode_free(struct inode *inode)
158191
iint_free(iint);
159192
}
160193

161-
static void init_once(void *foo)
194+
static void iint_init_once(void *foo)
162195
{
163196
struct integrity_iint_cache *iint = (struct integrity_iint_cache *) foo;
164197

165198
memset(iint, 0, sizeof(*iint));
166-
iint->ima_file_status = INTEGRITY_UNKNOWN;
167-
iint->ima_mmap_status = INTEGRITY_UNKNOWN;
168-
iint->ima_bprm_status = INTEGRITY_UNKNOWN;
169-
iint->ima_read_status = INTEGRITY_UNKNOWN;
170-
iint->ima_creds_status = INTEGRITY_UNKNOWN;
171-
iint->evm_status = INTEGRITY_UNKNOWN;
172-
mutex_init(&iint->mutex);
173199
}
174200

175201
static int __init integrity_iintcache_init(void)
176202
{
177203
iint_cache =
178204
kmem_cache_create("iint_cache", sizeof(struct integrity_iint_cache),
179-
0, SLAB_PANIC, init_once);
205+
0, SLAB_PANIC, iint_init_once);
180206
return 0;
181207
}
182208
DEFINE_LSM(integrity) = {

0 commit comments

Comments
 (0)