From: Roberto Sassu roberto.sassu@huawei.com
euleros inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7QZ2M CVE: NA
-------------------------------------------------
Currently, IMA supports the appraise_type=imasig option in the policy to require file signatures. This patch introduces the new option appraise_type=meta_immutable to require that file metadata are signed and immutable. This requirement can be satisfied by portable signatures and by digest lists if they are marked as immutable.
The main purpose of this option is to ensure that file metadata are correct at the time of access, so that policies relying on labels can be correctly enforced. For example, requiring immutable metadata would prevent an administrator from altering the label assigned to a process during execve() by changing the label of the executable.
Signed-off-by: Roberto Sassu roberto.sassu@huawei.com Signed-off-by: Tianxing Zhang zhangtianxing3@huawei.com Reviewed-by: Jason Yan yanaijie@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: zhoushuiqing zhoushuiqing2@huawei.com --- security/integrity/ima/ima_appraise.c | 10 ++++++++++ security/integrity/ima/ima_policy.c | 25 +++++++++++++++++++++++++ security/integrity/integrity.h | 3 +++ 3 files changed, 38 insertions(+)
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index a4178ed86..e6f07d2bf 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -665,6 +665,16 @@ int ima_appraise_measurement(enum ima_hooks func, default: WARN_ONCE(true, "Unexpected integrity status %d\n", status); } +#ifdef CONFIG_IMA_DIGEST_LIST + if ((iint->flags & IMA_META_IMMUTABLE_REQUIRED) && + status != INTEGRITY_PASS_IMMUTABLE) { + status = INTEGRITY_FAIL; + cause = "metadata-modifiable"; + integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, + filename, op, cause, rc, 0); + goto out; + } +#endif
if (xattr_value) rc = xattr_verify(func, iint, xattr_value, xattr_len, &status, diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 53a035ef0..4cabbe7f9 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -1257,7 +1257,12 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
if (entry->action != APPRAISE && entry->flags & (IMA_DIGSIG_REQUIRED | IMA_MODSIG_ALLOWED | +#ifdef CONFIG_IMA_DIGEST_LIST + IMA_CHECK_BLACKLIST | IMA_VALIDATE_ALGOS | + IMA_META_IMMUTABLE_REQUIRED)) +#else IMA_CHECK_BLACKLIST | IMA_VALIDATE_ALGOS)) +#endif return false;
/* @@ -1293,7 +1298,11 @@ static bool ima_validate_rule(struct ima_rule_entry *entry) IMA_FSNAME | IMA_GID | IMA_EGID | IMA_FGROUP | IMA_DIGSIG_REQUIRED | IMA_PERMIT_DIRECTIO | IMA_VALIDATE_ALGOS | +#ifdef CONFIG_IMA_DIGEST_LIST + IMA_VERITY_REQUIRED | IMA_META_IMMUTABLE_REQUIRED)) +#else IMA_VERITY_REQUIRED)) +#endif return false;
break; @@ -1306,7 +1315,12 @@ static bool ima_validate_rule(struct ima_rule_entry *entry) IMA_FSNAME | IMA_GID | IMA_EGID | IMA_FGROUP | IMA_DIGSIG_REQUIRED | IMA_PERMIT_DIRECTIO | IMA_MODSIG_ALLOWED | +#ifdef CONFIG_IMA_DIGEST_LIST + IMA_CHECK_BLACKLIST | IMA_VALIDATE_ALGOS | + IMA_META_IMMUTABLE_REQUIRED)) +#else IMA_CHECK_BLACKLIST | IMA_VALIDATE_ALGOS)) +#endif return false;
break; @@ -1834,9 +1848,16 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) else entry->flags |= IMA_DIGSIG_REQUIRED | IMA_MODSIG_ALLOWED; +#ifdef CONFIG_IMA_DIGEST_LIST + } else if (strcmp(args[0].from, "meta_immutable") == 0) + entry->flags |= IMA_META_IMMUTABLE_REQUIRED; + else + result = -EINVAL; +#else } else { result = -EINVAL; } +#endif break; case Opt_appraise_flag: ima_log_string(ab, "appraise_flag", args[0].from); @@ -2295,6 +2316,10 @@ int ima_policy_show(struct seq_file *m, void *v) seq_puts(m, "digest_type=verity "); if (entry->flags & IMA_CHECK_BLACKLIST) seq_puts(m, "appraise_flag=check_blacklist "); +#ifdef CONFIG_IMA_DIGEST_LIST + if (entry->flags & IMA_META_IMMUTABLE_REQUIRED) + seq_puts(m, "appraise_type=meta_immutable "); +#endif if (entry->flags & IMA_PERMIT_DIRECTIO) seq_puts(m, "permit_directio "); rcu_read_unlock(); diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 65d776e2e..54f75738f 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -45,6 +45,9 @@ #define IMA_MODSIG_ALLOWED 0x20000000 #define IMA_CHECK_BLACKLIST 0x40000000 #define IMA_VERITY_REQUIRED 0x80000000 +#ifdef CONFIG_IMA_DIGEST_LIST +#define IMA_META_IMMUTABLE_REQUIRED 0x100000000 +#endif
#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \ IMA_HASH | IMA_APPRAISE_SUBMASK)