// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2019 Microsoft Corporation
 *
 * Author: Lakshmi Ramasubramanian (nramas@linux.microsoft.com)
 *
 * File: ima_queue_keys.c
 *       Enables deferred processing of keys
 */

#include <linux/user_namespace.h>
#include <linux/workqueue.h>
#include <keys/asymmetric-type.h>
#include "ima.h"

/*
 * Flag to indicate whether a key can be processed
 * right away or should be queued for processing later.
 */
static bool ima_process_keys;

/*
 * To synchronize access to the list of keys that need to be measured
 */
static DEFINE_MUTEX(ima_keys_lock);
static LIST_HEAD(ima_keys);

/*
 * If custom IMA policy is not loaded then keys queued up
 * for measurement should be freed. This worker is used
 * for handling this scenario.
 */
static long ima_key_queue_timeout = 300000; /* 5 Minutes */
static void ima_keys_handler(struct work_struct *work);
static DECLARE_DELAYED_WORK(ima_keys_delayed_work, ima_keys_handler);
static bool timer_expired;

/*
 * This worker function frees keys that may still be
 * queued up in case custom IMA policy was not loaded.
 */
static void ima_keys_handler(struct work_struct *work)
{
	timer_expired = true;
	ima_process_queued_keys();
}

/*
 * This function sets up a worker to free queued keys in case
 * custom IMA policy was never loaded.
 */
void ima_init_key_queue(void)
{
	schedule_delayed_work(&ima_keys_delayed_work,
			      msecs_to_jiffies(ima_key_queue_timeout));
}

static void ima_free_key_entry(struct ima_key_entry *entry)
{
	if (entry) {
		kfree(entry->payload);
		kfree(entry->keyring_name);
		kfree(entry);
	}
}

static struct ima_key_entry *ima_alloc_key_entry(struct key *keyring,
						 const void *payload,
						 size_t payload_len)
{
	int rc = 0;
	const char *audit_cause = "ENOMEM";
	struct ima_key_entry *entry;

	entry = kzalloc_obj(*entry);
	if (entry) {
		entry->payload = kmemdup(payload, payload_len, GFP_KERNEL);
		entry->keyring_name = kstrdup(keyring->description,
					      GFP_KERNEL);
		entry->payload_len = payload_len;
	}

	if ((entry == NULL) || (entry->payload == NULL) ||
	    (entry->keyring_name == NULL)) {
		rc = -ENOMEM;
		goto out;
	}

	INIT_LIST_HEAD(&entry->list);

out:
	if (rc) {
		integrity_audit_message(AUDIT_INTEGRITY_PCR, NULL,
					keyring->description,
					func_measure_str(KEY_CHECK),
					audit_cause, rc, 0, rc);
		ima_free_key_entry(entry);
		entry = NULL;
	}

	return entry;
}

bool ima_queue_key(struct key *keyring, const void *payload,
		   size_t payload_len)
{
	bool queued = false;
	struct ima_key_entry *entry;

	entry = ima_alloc_key_entry(keyring, payload, payload_len);
	if (!entry)
		return false;

	mutex_lock(&ima_keys_lock);
	if (!ima_process_keys) {
		list_add_tail(&entry->list, &ima_keys);
		queued = true;
	}
	mutex_unlock(&ima_keys_lock);

	if (!queued)
		ima_free_key_entry(entry);

	return queued;
}

/*
 * ima_process_queued_keys() - process keys queued for measurement
 *
 * This function sets ima_process_keys to true and processes queued keys.
 * From here on keys will be processed right away (not queued).
 */
void ima_process_queued_keys(void)
{
	struct ima_key_entry *entry, *tmp;
	bool process = false;

	if (ima_process_keys)
		return;

	/*
	 * Since ima_process_keys is set to true, any new key will be
	 * processed immediately and not be queued to ima_keys list.
	 * First one setting the ima_process_keys flag to true will
	 * process the queued keys.
	 */
	mutex_lock(&ima_keys_lock);
	if (!ima_process_keys) {
		ima_process_keys = true;
		process = true;
	}
	mutex_unlock(&ima_keys_lock);

	if (!process)
		return;

	if (!timer_expired)
		cancel_delayed_work_sync(&ima_keys_delayed_work);

	list_for_each_entry_safe(entry, tmp, &ima_keys, list) {
		if (!timer_expired)
			process_buffer_measurement(&nop_mnt_idmap, NULL,
						   entry->payload,
						   entry->payload_len,
						   entry->keyring_name,
						   KEY_CHECK, 0,
						   entry->keyring_name,
						   false, NULL, 0);
		list_del(&entry->list);
		ima_free_key_entry(entry);
	}
}

inline bool ima_should_queue_key(void)
{
	return !ima_process_keys;
}
