diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 9f555532132053acfc529c7127030de4c7bcf087..fa9942e126b1b8d96525a4d441176f2b98dab65a 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -467,6 +467,8 @@ static bool ima_rule_contains_lsm_cond(struct ima_rule_entry *entry) return false; } +static DEFINE_MUTEX(ima_rules_mutex); + /* * The LSM policy can be reloaded, leaving the IMA LSM based rules referring * to the old, stale LSM policy. Update the IMA LSM based rules to reflect @@ -477,16 +479,19 @@ static void ima_lsm_update_rules(void) struct ima_rule_entry *entry, *e; int result; + mutex_lock(&ima_rules_mutex); list_for_each_entry_safe(entry, e, &ima_policy_rules, list) { if (!ima_rule_contains_lsm_cond(entry)) continue; result = ima_lsm_update_rule(entry); if (result) { + mutex_unlock(&ima_rules_mutex); pr_err("lsm rule update error %d\n", result); return; } } + mutex_unlock(&ima_rules_mutex); } int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event, @@ -1023,9 +1028,12 @@ int ima_check_policy(void) */ void ima_update_policy(void) { - struct list_head *policy = &ima_policy_rules; + struct list_head *policy; + mutex_lock(&ima_rules_mutex); + policy = &ima_policy_rules; list_splice_tail_init_rcu(&ima_temp_rules, policy, synchronize_rcu); + mutex_unlock(&ima_rules_mutex); if (ima_rules != (struct list_head __rcu *)policy) { ima_policy_flag = 0;