[PATCH 4.19 v3 6/6] ima: Handle -ESTALE returned by ima_filter_rule_match()
Guozihua (Scott)
guozihua at huawei.com
Mon Apr 17 11:39:01 UTC 2023
On 2023/2/28 16:06, GUO Zihua wrote:
> [ Upstream commit c7423dbdbc9ecef7fff5239d144cad4b9887f4de ]
>
> 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: b16942455193 ("ima: use the lsm policy update notifier")
> Signed-off-by: GUO Zihua <guozihua at huawei.com>
> Reviewed-by: Roberto Sassu <roberto.sassu at huawei.com>
> Signed-off-by: Mimi Zohar <zohar at linux.ibm.com>
> Signed-off-by: GUO Zihua <guozihua at huawei.com>
> ---
> security/integrity/ima/ima_policy.c | 40 ++++++++++++++++++++++-------
> 1 file changed, 31 insertions(+), 9 deletions(-)
>
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index 5256ff008f11..e9e15e622cf2 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -374,6 +374,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))
> @@ -412,38 +415,57 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
> int rc = 0;
> u32 osid;
>
> - if (!rule->lsm[i].rule) {
> - if (!rule->lsm[i].args_p)
> + if (!lsm_rule->lsm[i].rule) {
> + if (!lsm_rule->lsm[i].args_p)
> continue;
> else
> return false;
> }
> +
> +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;
> }
>
> /*
Ping?
--
Best
GUO Zihua
More information about the Linux-security-module-archive
mailing list