diff options
Diffstat (limited to 'security/integrity')
-rw-r--r-- | security/integrity/ima/ima.h | 1 | ||||
-rw-r--r-- | security/integrity/ima/ima_init.c | 4 | ||||
-rw-r--r-- | security/integrity/ima/ima_queue.c | 27 |
3 files changed, 31 insertions, 1 deletions
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index cc12f3449a72..89d65cf8053d 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -153,6 +153,7 @@ int ima_measurements_show(struct seq_file *m, void *v); unsigned long ima_get_binary_runtime_size(void); int ima_init_template(void); void ima_init_template_list(void); +int __init ima_init_digests(void); /* * used to protect h_table and sha_table diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 6bb42a9c5e47..6c9295449751 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -123,8 +123,12 @@ int __init ima_init(void) if (rc != 0) return rc; + /* It can be called before ima_init_digests(), it does not use TPM. */ ima_load_kexec_buffer(); + rc = ima_init_digests(); + if (rc != 0) + return rc; rc = ima_add_boot_aggregate(); /* boot aggregate must be first entry */ if (rc != 0) return rc; diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index 0e41dc1df1d4..6b6d044e0440 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -27,6 +27,9 @@ #define AUDIT_CAUSE_LEN_MAX 32 +/* pre-allocated array of tpm_digest structures to extend a PCR */ +static struct tpm_digest *digests; + LIST_HEAD(ima_measurements); /* list of all measurements */ #ifdef CONFIG_IMA_KEXEC static unsigned long binary_runtime_size; @@ -140,11 +143,15 @@ unsigned long ima_get_binary_runtime_size(void) static int ima_pcr_extend(const u8 *hash, int pcr) { int result = 0; + int i; if (!ima_tpm_chip) return result; - result = tpm_pcr_extend(ima_tpm_chip, pcr, hash); + for (i = 0; i < ima_tpm_chip->nr_allocated_banks; i++) + memcpy(digests[i].digest, hash, TPM_DIGEST_SIZE); + + result = tpm_pcr_extend(ima_tpm_chip, pcr, digests); if (result != 0) pr_err("Error Communicating to TPM chip, result: %d\n", result); return result; @@ -211,3 +218,21 @@ int ima_restore_measurement_entry(struct ima_template_entry *entry) mutex_unlock(&ima_extend_list_mutex); return result; } + +int __init ima_init_digests(void) +{ + int i; + + if (!ima_tpm_chip) + return 0; + + digests = kcalloc(ima_tpm_chip->nr_allocated_banks, sizeof(*digests), + GFP_NOFS); + if (!digests) + return -ENOMEM; + + for (i = 0; i < ima_tpm_chip->nr_allocated_banks; i++) + digests[i].alg_id = ima_tpm_chip->allocated_banks[i].alg_id; + + return 0; +} |