When both IMA and EVM fix modes are enabled, accessing a file with IMA signature won't cause security.evm to be fixed. But this doesn't happen to a file with correct IMA hash already set because accessing it will cause setting security.ima again which triggers fixing security.evm thanks to security_inode_post_setxattr->evm_update_evmxattr.
Let's use the same mechanism to fix security.evm for a file with IMA signature. Signed-off-by: Coiby Xu <c...@redhat.com> --- security/integrity/ima/ima_appraise.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index f435eff4667f..18c3907c5e44 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -595,12 +595,27 @@ int ima_appraise_measurement(enum ima_hooks func, struct ima_iint_cache *iint, integrity_audit_msg(audit_msgno, inode, filename, op, cause, rc, 0); } else if (status != INTEGRITY_PASS) { - /* Fix mode, but don't replace file signatures. */ - if ((ima_appraise & IMA_APPRAISE_FIX) && !try_modsig && - (!xattr_value || - xattr_value->type != EVM_IMA_XATTR_DIGSIG)) { - if (!ima_fix_xattr(dentry, iint)) - status = INTEGRITY_PASS; + /* + * Fix mode, but don't replace file signatures. + * + * When EVM fix mode is also enabled, security.evm will be + * fixed automatically when security.ima is set because of + * security_inode_post_setxattr->evm_update_evmxattr. + */ + if ((ima_appraise & IMA_APPRAISE_FIX) && !try_modsig) { + if (!xattr_value || + xattr_value->type != EVM_IMA_XATTR_DIGSIG) { + if (ima_fix_xattr(dentry, iint)) + status = INTEGRITY_PASS; + } else if (xattr_value->type == EVM_IMA_XATTR_DIGSIG && + evm_revalidate_status(XATTR_NAME_IMA)) { + if (!__vfs_setxattr_noperm(&nop_mnt_idmap, + dentry, + XATTR_NAME_IMA, + xattr_value, + xattr_len, 0)) + status = INTEGRITY_PASS; + } } /* base-commit: b320789d6883cc00ac78ce83bccbfe7ed58afcf0 -- 2.51.0