Skip to content

Commit c7423db

Browse files
GUO Zihuamimizohar
GUO Zihua
authored andcommitted
ima: Handle -ESTALE returned by ima_filter_rule_match()
IMA relies on the blocking LSM policy notifier callback to update the LSM based IMA policy rules. When SELinux update its policies, IMA would be notified and starts updating all its lsm rules one-by-one. During this time, -ESTALE would be returned by ima_filter_rule_match() if it is called with a LSM rule that has not yet been updated. In ima_match_rules(), -ESTALE is not handled, and the LSM rule is considered a match, causing extra files to be measured by IMA. Fix it by re-initializing a temporary rule if -ESTALE is returned by ima_filter_rule_match(). The origin rule in the rule list would be updated by the LSM policy notifier callback. Fixes: b169424 ("ima: use the lsm policy update notifier") Signed-off-by: GUO Zihua <[email protected]> Reviewed-by: Roberto Sassu <[email protected]> Signed-off-by: Mimi Zohar <[email protected]>
1 parent d57378d commit c7423db

File tree

1 file changed

+32
-9
lines changed

1 file changed

+32
-9
lines changed

security/integrity/ima/ima_policy.c

+32-9
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,9 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
545545
const char *func_data)
546546
{
547547
int i;
548+
bool result = false;
549+
struct ima_rule_entry *lsm_rule = rule;
550+
bool rule_reinitialized = false;
548551

549552
if ((rule->flags & IMA_FUNC) &&
550553
(rule->func != func && func != POST_SETATTR))
@@ -606,35 +609,55 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
606609
int rc = 0;
607610
u32 osid;
608611

609-
if (!rule->lsm[i].rule) {
610-
if (!rule->lsm[i].args_p)
612+
if (!lsm_rule->lsm[i].rule) {
613+
if (!lsm_rule->lsm[i].args_p)
611614
continue;
612615
else
613616
return false;
614617
}
618+
619+
retry:
615620
switch (i) {
616621
case LSM_OBJ_USER:
617622
case LSM_OBJ_ROLE:
618623
case LSM_OBJ_TYPE:
619624
security_inode_getsecid(inode, &osid);
620-
rc = ima_filter_rule_match(osid, rule->lsm[i].type,
625+
rc = ima_filter_rule_match(osid, lsm_rule->lsm[i].type,
621626
Audit_equal,
622-
rule->lsm[i].rule);
627+
lsm_rule->lsm[i].rule);
623628
break;
624629
case LSM_SUBJ_USER:
625630
case LSM_SUBJ_ROLE:
626631
case LSM_SUBJ_TYPE:
627-
rc = ima_filter_rule_match(secid, rule->lsm[i].type,
632+
rc = ima_filter_rule_match(secid, lsm_rule->lsm[i].type,
628633
Audit_equal,
629-
rule->lsm[i].rule);
634+
lsm_rule->lsm[i].rule);
630635
break;
631636
default:
632637
break;
633638
}
634-
if (!rc)
635-
return false;
639+
640+
if (rc == -ESTALE && !rule_reinitialized) {
641+
lsm_rule = ima_lsm_copy_rule(rule);
642+
if (lsm_rule) {
643+
rule_reinitialized = true;
644+
goto retry;
645+
}
646+
}
647+
if (!rc) {
648+
result = false;
649+
goto out;
650+
}
636651
}
637-
return true;
652+
result = true;
653+
654+
out:
655+
if (rule_reinitialized) {
656+
for (i = 0; i < MAX_LSM_RULES; i++)
657+
ima_filter_rule_free(lsm_rule->lsm[i].rule);
658+
kfree(lsm_rule);
659+
}
660+
return result;
638661
}
639662

640663
/*

0 commit comments

Comments
 (0)