0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <linux/rculist.h>
0019 #include <linux/slab.h>
0020 #include "ima.h"
0021
0022 #define AUDIT_CAUSE_LEN_MAX 32
0023
0024
0025 static struct tpm_digest *digests;
0026
0027 LIST_HEAD(ima_measurements);
0028 #ifdef CONFIG_IMA_KEXEC
0029 static unsigned long binary_runtime_size;
0030 #else
0031 static unsigned long binary_runtime_size = ULONG_MAX;
0032 #endif
0033
0034
0035 struct ima_h_table ima_htable = {
0036 .len = ATOMIC_LONG_INIT(0),
0037 .violations = ATOMIC_LONG_INIT(0),
0038 .queue[0 ... IMA_MEASURE_HTABLE_SIZE - 1] = HLIST_HEAD_INIT
0039 };
0040
0041
0042
0043
0044
0045 static DEFINE_MUTEX(ima_extend_list_mutex);
0046
0047
0048 static struct ima_queue_entry *ima_lookup_digest_entry(u8 *digest_value,
0049 int pcr)
0050 {
0051 struct ima_queue_entry *qe, *ret = NULL;
0052 unsigned int key;
0053 int rc;
0054
0055 key = ima_hash_key(digest_value);
0056 rcu_read_lock();
0057 hlist_for_each_entry_rcu(qe, &ima_htable.queue[key], hnext) {
0058 rc = memcmp(qe->entry->digests[ima_hash_algo_idx].digest,
0059 digest_value, hash_digest_size[ima_hash_algo]);
0060 if ((rc == 0) && (qe->entry->pcr == pcr)) {
0061 ret = qe;
0062 break;
0063 }
0064 }
0065 rcu_read_unlock();
0066 return ret;
0067 }
0068
0069
0070
0071
0072
0073
0074 static int get_binary_runtime_size(struct ima_template_entry *entry)
0075 {
0076 int size = 0;
0077
0078 size += sizeof(u32);
0079 size += TPM_DIGEST_SIZE;
0080 size += sizeof(int);
0081 size += strlen(entry->template_desc->name);
0082 size += sizeof(entry->template_data_len);
0083 size += entry->template_data_len;
0084 return size;
0085 }
0086
0087
0088
0089
0090
0091
0092
0093 static int ima_add_digest_entry(struct ima_template_entry *entry,
0094 bool update_htable)
0095 {
0096 struct ima_queue_entry *qe;
0097 unsigned int key;
0098
0099 qe = kmalloc(sizeof(*qe), GFP_KERNEL);
0100 if (qe == NULL) {
0101 pr_err("OUT OF MEMORY ERROR creating queue entry\n");
0102 return -ENOMEM;
0103 }
0104 qe->entry = entry;
0105
0106 INIT_LIST_HEAD(&qe->later);
0107 list_add_tail_rcu(&qe->later, &ima_measurements);
0108
0109 atomic_long_inc(&ima_htable.len);
0110 if (update_htable) {
0111 key = ima_hash_key(entry->digests[ima_hash_algo_idx].digest);
0112 hlist_add_head_rcu(&qe->hnext, &ima_htable.queue[key]);
0113 }
0114
0115 if (binary_runtime_size != ULONG_MAX) {
0116 int size;
0117
0118 size = get_binary_runtime_size(entry);
0119 binary_runtime_size = (binary_runtime_size < ULONG_MAX - size) ?
0120 binary_runtime_size + size : ULONG_MAX;
0121 }
0122 return 0;
0123 }
0124
0125
0126
0127
0128
0129
0130 unsigned long ima_get_binary_runtime_size(void)
0131 {
0132 if (binary_runtime_size >= (ULONG_MAX - sizeof(struct ima_kexec_hdr)))
0133 return ULONG_MAX;
0134 else
0135 return binary_runtime_size + sizeof(struct ima_kexec_hdr);
0136 }
0137
0138 static int ima_pcr_extend(struct tpm_digest *digests_arg, int pcr)
0139 {
0140 int result = 0;
0141
0142 if (!ima_tpm_chip)
0143 return result;
0144
0145 result = tpm_pcr_extend(ima_tpm_chip, pcr, digests_arg);
0146 if (result != 0)
0147 pr_err("Error Communicating to TPM chip, result: %d\n", result);
0148 return result;
0149 }
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159 int ima_add_template_entry(struct ima_template_entry *entry, int violation,
0160 const char *op, struct inode *inode,
0161 const unsigned char *filename)
0162 {
0163 u8 *digest = entry->digests[ima_hash_algo_idx].digest;
0164 struct tpm_digest *digests_arg = entry->digests;
0165 const char *audit_cause = "hash_added";
0166 char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX];
0167 int audit_info = 1;
0168 int result = 0, tpmresult = 0;
0169
0170 mutex_lock(&ima_extend_list_mutex);
0171 if (!violation && !IS_ENABLED(CONFIG_IMA_DISABLE_HTABLE)) {
0172 if (ima_lookup_digest_entry(digest, entry->pcr)) {
0173 audit_cause = "hash_exists";
0174 result = -EEXIST;
0175 goto out;
0176 }
0177 }
0178
0179 result = ima_add_digest_entry(entry,
0180 !IS_ENABLED(CONFIG_IMA_DISABLE_HTABLE));
0181 if (result < 0) {
0182 audit_cause = "ENOMEM";
0183 audit_info = 0;
0184 goto out;
0185 }
0186
0187 if (violation)
0188 digests_arg = digests;
0189
0190 tpmresult = ima_pcr_extend(digests_arg, entry->pcr);
0191 if (tpmresult != 0) {
0192 snprintf(tpm_audit_cause, AUDIT_CAUSE_LEN_MAX, "TPM_error(%d)",
0193 tpmresult);
0194 audit_cause = tpm_audit_cause;
0195 audit_info = 0;
0196 }
0197 out:
0198 mutex_unlock(&ima_extend_list_mutex);
0199 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename,
0200 op, audit_cause, result, audit_info);
0201 return result;
0202 }
0203
0204 int ima_restore_measurement_entry(struct ima_template_entry *entry)
0205 {
0206 int result = 0;
0207
0208 mutex_lock(&ima_extend_list_mutex);
0209 result = ima_add_digest_entry(entry, 0);
0210 mutex_unlock(&ima_extend_list_mutex);
0211 return result;
0212 }
0213
0214 int __init ima_init_digests(void)
0215 {
0216 u16 digest_size;
0217 u16 crypto_id;
0218 int i;
0219
0220 if (!ima_tpm_chip)
0221 return 0;
0222
0223 digests = kcalloc(ima_tpm_chip->nr_allocated_banks, sizeof(*digests),
0224 GFP_NOFS);
0225 if (!digests)
0226 return -ENOMEM;
0227
0228 for (i = 0; i < ima_tpm_chip->nr_allocated_banks; i++) {
0229 digests[i].alg_id = ima_tpm_chip->allocated_banks[i].alg_id;
0230 digest_size = ima_tpm_chip->allocated_banks[i].digest_size;
0231 crypto_id = ima_tpm_chip->allocated_banks[i].crypto_id;
0232
0233
0234 if (crypto_id == HASH_ALGO__LAST)
0235 digest_size = SHA1_DIGEST_SIZE;
0236
0237 memset(digests[i].digest, 0xff, digest_size);
0238 }
0239
0240 return 0;
0241 }