Skip to content

Commit 9df6a48

Browse files
uudiinmimizohar
authored andcommitted
integrity: Fix possible multiple allocation in integrity_inode_get()
When integrity_inode_get() is querying and inserting the cache, there is a conditional race in the concurrent environment. The race condition is the result of not properly implementing "double-checked locking". In this case, it first checks to see if the iint cache record exists before taking the lock, but doesn't check again after taking the integrity_iint_lock. Fixes: bf2276d ("ima: allocating iint improvements") Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com> Cc: Dmitry Kasatkin <dmitry.kasatkin@gmail.com> Cc: <stable@vger.kernel.org> # v3.10+ Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
1 parent db1d1e8 commit 9df6a48

1 file changed

Lines changed: 9 additions & 6 deletions

File tree

security/integrity/iint.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,10 @@ static struct integrity_iint_cache *__integrity_iint_find(struct inode *inode)
4343
else if (inode > iint->inode)
4444
n = n->rb_right;
4545
else
46-
break;
46+
return iint;
4747
}
48-
if (!n)
49-
return NULL;
5048

51-
return iint;
49+
return NULL;
5250
}
5351

5452
/*
@@ -113,10 +111,15 @@ struct integrity_iint_cache *integrity_inode_get(struct inode *inode)
113111
parent = *p;
114112
test_iint = rb_entry(parent, struct integrity_iint_cache,
115113
rb_node);
116-
if (inode < test_iint->inode)
114+
if (inode < test_iint->inode) {
117115
p = &(*p)->rb_left;
118-
else
116+
} else if (inode > test_iint->inode) {
119117
p = &(*p)->rb_right;
118+
} else {
119+
write_unlock(&integrity_iint_lock);
120+
kmem_cache_free(iint_cache, iint);
121+
return test_iint;
122+
}
120123
}
121124

122125
iint->inode = inode;

0 commit comments

Comments
 (0)