From: Krzysztof Struczynski krzysztof.struczynski@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I49KW1 CVE: NA
--------------------------------
Add ima namespace id to the ima_event_data and ima_template_entry. This is done so that the template entries can be tracked per ima namespace. The following patches will add new templates that will include the namespace id, but the namespace id has to be stored separately so that the namespace functionality is enabled for every template.
After kexec, all entries from the old measurement list will be associated with the new root ima namespace. This will prevent users in the new ima namespaces from accessing the old entries if the ima namespace id is reused.
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.h | 10 +++++++++- security/integrity/ima/ima_api.c | 8 +++++++- security/integrity/ima/ima_init.c | 2 ++ security/integrity/ima/ima_main.c | 5 +++-- security/integrity/ima/ima_template.c | 2 ++ 5 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 1a1c1eebc01c..324ccfbbc1dc 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -80,6 +80,7 @@ struct ima_event_data { const char *violation; const void *buf; int buf_len; + unsigned int ns_id; };
/* IMA template field data definition */ @@ -108,6 +109,7 @@ struct ima_template_desc {
struct ima_template_entry { int pcr; + unsigned int ns_id; struct tpm_digest *digests; struct ima_template_desc *template_desc; /* template descriptor */ u32 template_data_len; @@ -158,7 +160,8 @@ int ima_calc_field_array_hash(struct ima_field_data *field_data, int ima_calc_boot_aggregate(struct ima_digest_data *hash); void ima_add_violation(struct file *file, const unsigned char *filename, struct integrity_iint_cache *iint, - const char *op, const char *cause); + const char *op, const char *cause, + struct ima_namespace *ima_ns); int ima_init_crypto(void); void ima_putc(struct seq_file *m, void *data, int datalen); void ima_print_digest(struct seq_file *m, u8 *digest, u32 size); @@ -409,6 +412,11 @@ extern struct ima_policy_setup_data init_policy_setup_data; extern struct list_head ima_ns_list; extern struct rw_semaphore ima_ns_list_lock;
+static inline unsigned int get_ns_id(const struct ima_namespace *ima_ns) +{ + return ima_ns->ns.inum; +} + #ifdef CONFIG_IMA_NS int __init ima_init_namespace(void);
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index 743b9337d9e5..2678faaa7a15 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -76,6 +76,8 @@ int ima_alloc_init_template(struct ima_event_data *event_data, (*entry)->template_data_len += sizeof(len); (*entry)->template_data_len += len; } + + (*entry)->ns_id = event_data->ns_id; return 0; out: ima_free_template_entry(*entry); @@ -152,7 +154,8 @@ int ima_store_template(struct ima_template_entry *entry, */ void ima_add_violation(struct file *file, const unsigned char *filename, struct integrity_iint_cache *iint, - const char *op, const char *cause) + const char *op, const char *cause, + struct ima_namespace *ima_ns) { struct ima_template_entry *entry; struct inode *inode = file_inode(file); @@ -163,6 +166,8 @@ void ima_add_violation(struct file *file, const unsigned char *filename, int violation = 1; int result;
+ event_data.ns_id = get_ns_id(ima_ns); + /* can overflow, only indicator */ atomic_long_inc(&ima_htable.violations);
@@ -336,6 +341,7 @@ void ima_store_measurement(struct integrity_iint_cache *iint, .modsig = modsig }; int violation = 0;
+ event_data.ns_id = get_ns_id(ima_ns); /* * We still need to store the measurement in the case of MODSIG because * we only have its contents to put in the list at the time of diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index dea0251142fd..52b675d47177 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -68,6 +68,8 @@ static int __init ima_add_boot_aggregate(void) char digest[TPM_MAX_DIGEST_SIZE]; } hash;
+ event_data.ns_id = get_ns_id(&init_ima_ns); + memset(iint, 0, sizeof(*iint)); memset(&hash, 0, sizeof(hash)); iint->ima_hash = &hash.hdr; diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index e0460462193d..18291787dbb5 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -149,10 +149,10 @@ static void ima_rdwr_violation_check(struct file *file,
if (send_tomtou) ima_add_violation(file, *pathname, iint, - "invalid_pcr", "ToMToU"); + "invalid_pcr", "ToMToU", ima_ns); if (send_writers) ima_add_violation(file, *pathname, iint, - "invalid_pcr", "open_writers"); + "invalid_pcr", "open_writers", ima_ns); }
static enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, @@ -1068,6 +1068,7 @@ void process_buffer_measurement(struct inode *inode, const void *buf, int size, goto out; }
+ event_data.ns_id = get_ns_id(ima_ns); ret = ima_alloc_init_template(&event_data, &entry, template); if (ret < 0) { audit_cause = "alloc_entry"; diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index 0d4c698d2707..db4d3893d32d 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c @@ -373,6 +373,7 @@ int ima_restore_measurement_list(loff_t size, void *buf) struct ima_template_desc *template_desc; DECLARE_BITMAP(hdr_mask, HDR__LAST); unsigned long count = 0; + unsigned int init_ns_id = get_ns_id(&init_ima_ns); int ret = 0;
if (!buf || size < sizeof(*khdr)) @@ -472,6 +473,7 @@ int ima_restore_measurement_list(loff_t size, void *buf)
entry->pcr = !ima_canonical_fmt ? *(u32 *)(hdr[HDR_PCR].data) : le32_to_cpu(*(u32 *)(hdr[HDR_PCR].data)); + entry->ns_id = init_ns_id; ret = ima_restore_measurement_entry(entry); if (ret < 0) break;