// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2005,2006,2007,2008 IBM Corporation * * Authors: * Serge Hallyn <serue@us.ibm.com> * Reiner Sailer <sailer@watson.ibm.com> * Mimi Zohar <zohar@us.ibm.com> * * File: ima_queue.c * Implements queues that store template measurements and * maintains aggregate over the stored measurements * in the pre-configured TPM PCR (if available). * The measurement list is append-only. No entry is * ever removed or changed during the boot-cycle.
*/
/* mutex protects atomicity of extending measurement list * and extending the TPM PCR aggregate. Since tpm_extend can take * long (and the tpm driver uses a mutex), we can't use the spinlock.
*/ static DEFINE_MUTEX(ima_extend_list_mutex);
/* * Used internally by the kernel to suspend measurements. * Protected by ima_extend_list_mutex.
*/ staticbool ima_measurements_suspended;
/* lookup up the digest value in the hash table, and return the entry */ staticstruct ima_queue_entry *ima_lookup_digest_entry(u8 *digest_value, int pcr)
{ struct ima_queue_entry *qe, *ret = NULL; unsignedint key; int rc;
/* * Calculate the memory required for serializing a single * binary_runtime_measurement list entry, which contains a * couple of variable length fields (e.g template name and data).
*/ staticint get_binary_runtime_size(struct ima_template_entry *entry)
{ int size = 0;
/* ima_add_template_entry helper function: * - Add template entry to the measurement list and hash table, for * all entries except those carried across kexec. * * (Called with ima_extend_list_mutex held.)
*/ staticint ima_add_digest_entry(struct ima_template_entry *entry, bool update_htable)
{ struct ima_queue_entry *qe; unsignedint key;
qe = kmalloc(sizeof(*qe), GFP_KERNEL); if (qe == NULL) {
pr_err("OUT OF MEMORY ERROR creating queue entry\n"); return -ENOMEM;
}
qe->entry = entry;
/* * Return the amount of memory required for serializing the * entire binary_runtime_measurement list, including the ima_kexec_hdr * structure.
*/ unsignedlong ima_get_binary_runtime_size(void)
{ if (binary_runtime_size >= (ULONG_MAX - sizeof(struct ima_kexec_hdr))) return ULONG_MAX; else return binary_runtime_size + sizeof(struct ima_kexec_hdr);
}
staticint ima_pcr_extend(struct tpm_digest *digests_arg, int pcr)
{ int result = 0;
if (!ima_tpm_chip) return result;
result = tpm_pcr_extend(ima_tpm_chip, pcr, digests_arg); if (result != 0)
pr_err("Error Communicating to TPM chip, result: %d\n", result); return result;
}
/* * Add template entry to the measurement list and hash table, and * extend the pcr. * * On systems which support carrying the IMA measurement list across * kexec, maintain the total memory size required for serializing the * binary_runtime_measurements.
*/ int ima_add_template_entry(struct ima_template_entry *entry, int violation, constchar *op, struct inode *inode, constunsignedchar *filename)
{
u8 *digest = entry->digests[ima_hash_algo_idx].digest; struct tpm_digest *digests_arg = entry->digests; constchar *audit_cause = "hash_added"; char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX]; int audit_info = 1; int result = 0, tpmresult = 0;
mutex_lock(&ima_extend_list_mutex);
/* * Avoid appending to the measurement log when the TPM subsystem has * been shut down while preparing for system reboot.
*/ if (ima_measurements_suspended) {
audit_cause = "measurements_suspended";
audit_info = 0;
result = -ENODEV; goto out;
}
if (!violation && !IS_ENABLED(CONFIG_IMA_DISABLE_HTABLE)) { if (ima_lookup_digest_entry(digest, entry->pcr)) {
audit_cause = "hash_exists";
result = -EEXIST; goto out;
}
}
result = ima_add_digest_entry(entry,
!IS_ENABLED(CONFIG_IMA_DISABLE_HTABLE)); if (result < 0) {
audit_cause = "ENOMEM";
audit_info = 0; goto out;
}
if (violation) /* invalidate pcr */
digests_arg = digests;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.