From: Krzysztof Struczynski krzysztof.struczynski@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I49KW1 CVE: NA
--------------------------------
Add dummy boot aggregate entry to the ima measurement list, for every new ima namespace, when the first process is born into that namespace.
There is at most one TPM chip in the system and one measurement list associated to one of its PCRs. IMA namespace IDs can be re-used after namespace is destroyed. The per namespace boot aggregate entry marks the moment of the ima namespace creation. It is useful when host's root parses the global measurement list to find entries for destroyed containers. If the ima namespace ID is reused, the user will know, that the given entry belongs to a different container.
Signed-off-by: Krzysztof Struczynski krzysztof.struczynski@huawei.com Reviewed-by: Zhang Tianxing zhangtianxing3@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- security/integrity/ima/ima_ns.c | 62 +++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+)
diff --git a/security/integrity/ima/ima_ns.c b/security/integrity/ima/ima_ns.c index b04f35f35f85..29a1cbdac40d 100644 --- a/security/integrity/ima/ima_ns.c +++ b/security/integrity/ima/ima_ns.c @@ -49,6 +49,66 @@ static void dec_ima_namespaces(struct ucounts *ucounts) return dec_ucount(ucounts, UCOUNT_IMA_NAMESPACES); }
+static int ima_ns_add_boot_aggregate(struct ima_namespace *ima_ns) +{ + static const char op[] = "ns_add_boot_aggregate"; + static const char ns_aggregate_name_prefix[] = "ns_aggregate_"; + const char *audit_cause = "ENOMEM"; + struct ima_template_entry *entry; + struct integrity_iint_cache tmp_iint, *iint = &tmp_iint; + struct ima_event_data event_data = { .iint = iint }; + int result = -ENOMEM; + int violation = 0; + struct { + struct ima_digest_data hdr; + char digest[TPM_DIGEST_SIZE]; + } hash; + unsigned int ns_id = get_ns_id(ima_ns); + char *ns_aggregate_name; + + ns_aggregate_name = kmalloc(sizeof(ns_aggregate_name_prefix) + + sizeof(unsigned int), + GFP_KERNEL); + if (!ns_aggregate_name) + goto err_out; + + sprintf(ns_aggregate_name, "%s%u", ns_aggregate_name_prefix, ns_id); + + event_data.filename = ns_aggregate_name; + event_data.ns_id = ns_id; + + memset(iint, 0, sizeof(*iint)); + memset(&hash, 0, sizeof(hash)); + iint->ima_hash = &hash.hdr; + iint->ima_hash->algo = HASH_ALGO_SHA1; + iint->ima_hash->length = SHA1_DIGEST_SIZE; + + result = ima_alloc_init_template(&event_data, &entry, NULL); + if (result < 0) { + audit_cause = "alloc_entry"; + goto err_out; + } + + result = ima_store_template(entry, violation, NULL, + ns_aggregate_name, + CONFIG_IMA_MEASURE_PCR_IDX, + NULL, + ima_ns); + if (result < 0) { + ima_free_template_entry(entry); + audit_cause = "store_entry"; + } + +err_out: + if (result < 0) + integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, + ns_aggregate_name, op, audit_cause, + result, 0); + kfree(ns_aggregate_name); + + return result; +} + #ifdef CONFIG_IMA_LOAD_X509 static int ima_ns_load_x509(struct ima_namespace *ima_ns) { @@ -385,6 +445,8 @@ static int imans_activate(struct ima_namespace *ima_ns) list_add_tail(&ima_ns->list, &ima_ns_list); up_write(&ima_ns_list_lock);
+ ima_ns_add_boot_aggregate(ima_ns); + /* The x509 certificate has to be measured in the new namespace as * well as in the parent namespace, therefore it has to be loaded * after adding the namespace to the list of active namespaces. If