security/integrity/ima/ima_queue.c

Source file repositories/reference/linux-study-clean/security/integrity/ima/ima_queue.c

File Facts

System
Linux kernel
Corpus path
security/integrity/ima/ima_queue.c
Extension
.c
Size
15635 bytes
Lines
578
Domain
Core OS
Bucket
Security And Isolation
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if ((rc == 0) && (qe->entry->pcr == pcr)) {
			ret = qe;
			break;
		}
	}
	rcu_read_unlock();
	return ret;
}

/*
 * 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).
 */
static int get_binary_runtime_size(struct ima_template_entry *entry)
{
	int size = 0;

	size += sizeof(u32);	/* pcr */
	size += TPM_DIGEST_SIZE;
	size += sizeof(int);	/* template name size field */
	size += strlen(entry->template_desc->name);
	size += sizeof(entry->template_data_len);
	size += entry->template_data_len;
	return size;
}

static void ima_update_binary_runtime_size(struct ima_template_entry *entry,
					   enum binary_lists binary_list)
{
	int size;

	if (binary_runtime_size[binary_list] == ULONG_MAX)
		return;

	size = get_binary_runtime_size(entry);
	binary_runtime_size[binary_list] =
		(binary_runtime_size[binary_list] < ULONG_MAX - size) ?
		binary_runtime_size[binary_list] + size : ULONG_MAX;
}

/* 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.)
 */
static int ima_add_digest_entry(struct ima_template_entry *entry,
				bool update_htable)
{
	struct ima_queue_entry *qe;
	struct hlist_head *htable;
	unsigned int key;

	qe = kmalloc_obj(*qe);
	if (qe == NULL) {
		pr_err("OUT OF MEMORY ERROR creating queue entry\n");
		return -ENOMEM;
	}
	qe->entry = entry;

	INIT_LIST_HEAD(&qe->later);
	list_add_tail_rcu(&qe->later, &ima_measurements);

	htable = rcu_dereference_protected(ima_htable,
				lockdep_is_held(&ima_extend_list_mutex));

	atomic_long_inc(&ima_num_records[BINARY]);
	atomic_long_inc(&ima_num_records[BINARY_FULL]);

	if (update_htable) {
		key = ima_hash_key(entry->digests[ima_hash_algo_idx].digest);
		hlist_add_head_rcu(&qe->hnext, &htable[key]);
	}

	ima_update_binary_runtime_size(entry, BINARY);
	ima_update_binary_runtime_size(entry, BINARY_FULL);

	return 0;
}

/*
 * Return the amount of memory required for serializing the
 * entire binary_runtime_measurement list, including the ima_kexec_hdr
 * structure.
 */
unsigned long ima_get_binary_runtime_size(enum binary_lists binary_list)
{
	unsigned long val;

Annotation

Implementation Notes