[PATCH v5 2/2] ima: Handle -ESTALE returned by ima_filter_rule_match()
Guozihua (Scott)
guozihua at huawei.com
Sat Sep 24 06:05:12 UTC 2022
On 2022/9/23 19:19, Mimi Zohar wrote:
> On Fri, 2022-09-23 at 12:01 +0800, Guozihua (Scott) wrote:
>> On 2022/9/22 19:09, Mimi Zohar wrote:
>>> Hi Scott,
>>>
>>> On Wed, 2022-09-21 at 20:58 +0800, GUO Zihua wrote:
>>>> }
>>>> - if (!rc)
>>>> - return false;
>>>> +
>>>> + if (rc == -ESTALE && !rule_reinitialized) {
>>>
>>> Ok, this limits allocating ima_lsm_copy_rule() to the first -ESTALE,
>>>
>>>> + lsm_rule = ima_lsm_copy_rule(rule);
>>>> + if (lsm_rule) {
>>>> + rule_reinitialized = true;
>>>> + goto retry;
>>>
>>> but "retry" is also limited to the first -ESTALE.
>>
>> Technically we would only need one retry. This loop is looping on all
>> the lsm members of one rule, and ima_lsm_copy_rule would update all the
>> lsm members of this rule. The "lsm member" here refers to LSM defined
>> properties like obj_user, obj_role etc. These members are of AND
>> relation, meaning all lsm members together would form one LSM rule.
>>
>> As of the scenario you mentioned, I think it should be really rare.
>> Spending to much time and code on this might not worth it.
>>>
>>>> + }
>>>> + }
>
> Either there can be multiple LSM fields and the memory is allocated
> once and freed once at the end, as you suggested, or the memory should
> be freed here and rule_reinitialized reset, minimizing the code change.
I might have overlooked something, but if I understands the code
correctly, we would be copying the same rule over and over again till
the loop ends in that case. ima_lsm_update_rule() would replace the rule
node on the rule list without updating the rule in place. Although
synchronize_rcu() should prevent a UAF, the rule in ima_match_rules()
would not be updated. Meaning SELinux would always return -ESTALE before
we copy and retry as we keep passing in the outdated rule entry.
>
>>>> + if (!rc) {
>>>> + result = false;
>>>> + goto out;
>>>> + }
>>>> }
>>>> - return true;
>>>> + result = true;
>>>> +
>>>> +out:
>>>> + if (rule_reinitialized) {
>>>> + for (i = 0; i < MAX_LSM_RULES; i++)
>>>> + ima_filter_rule_free(lsm_rule->lsm[i].rule);
>>>> + kfree(lsm_rule);
>>>> + }
>>>> + return result;
>>>> }
>
--
Best
GUO Zihua
More information about the Linux-security-module-archive
mailing list