From: Roberto Sassu roberto.sassu@huawei.com
hulk inclusion category: feature feature: IMA Digest Lists extension bugzilla: 46797
-------------------------------------------------
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 | 9 +++++++++ security/integrity/ima/ima_policy.c | 14 ++++++++++---- security/integrity/integrity.h | 1 + 3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 785849243048..5eca0fb771aa 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -617,6 +617,15 @@ int ima_appraise_measurement(enum ima_hooks func, WARN_ONCE(true, "Unexpected integrity status %d\n", status); }
+ 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; + } + if (xattr_value) rc = xattr_verify(func, iint, xattr_value, xattr_len, &status, &cause, found_digest); diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 0c7f135bb556..66eaa0e0f66f 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -1251,7 +1251,8 @@ static bool ima_validate_rule(struct ima_rule_entry *entry)
if (entry->action != APPRAISE && entry->flags & (IMA_DIGSIG_REQUIRED | IMA_MODSIG_ALLOWED | - IMA_CHECK_BLACKLIST | IMA_VALIDATE_ALGOS)) + IMA_CHECK_BLACKLIST | IMA_VALIDATE_ALGOS | + IMA_META_IMMUTABLE_REQUIRED)) return false;
/* @@ -1285,7 +1286,7 @@ 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 | - IMA_VERITY_REQUIRED)) + IMA_VERITY_REQUIRED | IMA_META_IMMUTABLE_REQUIRED)) return false;
break; @@ -1298,7 +1299,8 @@ 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 | - IMA_CHECK_BLACKLIST | IMA_VALIDATE_ALGOS)) + IMA_CHECK_BLACKLIST | IMA_VALIDATE_ALGOS | + IMA_META_IMMUTABLE_REQUIRED)) return false;
break; @@ -1824,7 +1826,9 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) else entry->flags |= IMA_DIGSIG_REQUIRED | IMA_MODSIG_ALLOWED; - } else { + } else if (strcmp(args[0].from, "meta_immutable") == 0) + entry->flags |= IMA_META_IMMUTABLE_REQUIRED; + else { result = -EINVAL; } break; @@ -2281,6 +2285,8 @@ 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 "); + if (entry->flags & IMA_META_IMMUTABLE_REQUIRED) + seq_puts(m, "appraise_type=meta_immutable "); 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 eea4adb46fdd..a93ad2bcd809 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h @@ -43,6 +43,7 @@ #define IMA_MODSIG_ALLOWED 0x20000000 #define IMA_CHECK_BLACKLIST 0x40000000 #define IMA_VERITY_REQUIRED 0x80000000 +#define IMA_META_IMMUTABLE_REQUIRED 0x100000000
#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \ IMA_HASH | IMA_APPRAISE_SUBMASK)