diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 1a1c1eebc01c0bff5bafe10f66fc821892c93693..324ccfbbc1dc3bb06b938b7f221136d2d7e85621 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 743b9337d9e573f9db8d2b69432e09d5b0ff93a9..2678faaa7a15d55185ad20146067e83ff2cdce0e 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 dea0251142fd5b41c1733378309ca4d50a434aae..52b675d47177b44aa48ed76b014272edbaec17d6 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 e0460462193d73f8f49f6d3d34f74e3955a9f0c4..18291787dbb56b91423deac1c2ca9024ef9800ab 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 0d4c698d2707e0281469f60d288c2f4049c867cb..db4d3893d32d70d665cd7e42979bd0f80a8640f4 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;