Skip to content

Commit fce754e

Browse files
committed
Merge: IMA and overlayfs, lock dependency false flag resolution
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/7135 JIRA: https://issues.redhat.com/browse/RHEL-59837 Backport to resolve lockdep warnings coming from overlayfs when using IMA. Signed-off-by: Aaron Brookner <abrookne@redhat.com> Approved-by: Jerry Snitselaar <jsnitsel@redhat.com> Approved-by: Jared Kangas <jkangas@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Approved-by: Richard Guy Briggs <rgb@redhat.com> Merged-by: Jarod Wilson <jarod@redhat.com>
2 parents bd3875a + 39b755d commit fce754e

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)