@@ -375,6 +375,9 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
enum ima_hooks func, int mask)
{
int i;
+ bool result = false;
+ struct ima_rule_entry *lsm_rule = rule;
+ bool rule_reinitialized = false;
if ((rule->flags & IMA_FUNC) &&
(rule->func != func && func != POST_SETATTR))
@@ -413,35 +416,53 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
int rc = 0;
u32 osid;
- if (!rule->lsm[i].rule)
+ if (!lsm_rule->lsm[i].rule)
continue;
+retry:
switch (i) {
case LSM_OBJ_USER:
case LSM_OBJ_ROLE:
case LSM_OBJ_TYPE:
security_inode_getsecid(inode, &osid);
rc = security_filter_rule_match(osid,
- rule->lsm[i].type,
+ lsm_rule->lsm[i].type,
Audit_equal,
- rule->lsm[i].rule,
+ lsm_rule->lsm[i].rule,
NULL);
break;
case LSM_SUBJ_USER:
case LSM_SUBJ_ROLE:
case LSM_SUBJ_TYPE:
rc = security_filter_rule_match(secid,
- rule->lsm[i].type,
+ lsm_rule->lsm[i].type,
Audit_equal,
- rule->lsm[i].rule,
+ lsm_rule->lsm[i].rule,
NULL);
default:
break;
}
- if (!rc)
- return false;
+
+ if (rc == -ESTALE && !rule_reinitialized) {
+ lsm_rule = ima_lsm_copy_rule(rule);
+ if (lsm_rule) {
+ rule_reinitialized = true;
+ goto retry;
+ }
+ }
+ if (!rc) {
+ result = false;
+ goto out;
+ }
+ }
+ result = true;
+
+out:
+ if (rule_reinitialized) {
+ ima_lsm_free_rule(lsm_rule);
+ kfree(lsm_rule);
}
- return true;
+ return result;
}
/*