Path: blob/master/security/integrity/ima/ima_queue_keys.c
26424 views
// SPDX-License-Identifier: GPL-2.0+1/*2* Copyright (C) 2019 Microsoft Corporation3*4* Author: Lakshmi Ramasubramanian ([email protected])5*6* File: ima_queue_keys.c7* Enables deferred processing of keys8*/910#include <linux/user_namespace.h>11#include <linux/workqueue.h>12#include <keys/asymmetric-type.h>13#include "ima.h"1415/*16* Flag to indicate whether a key can be processed17* right away or should be queued for processing later.18*/19static bool ima_process_keys;2021/*22* To synchronize access to the list of keys that need to be measured23*/24static DEFINE_MUTEX(ima_keys_lock);25static LIST_HEAD(ima_keys);2627/*28* If custom IMA policy is not loaded then keys queued up29* for measurement should be freed. This worker is used30* for handling this scenario.31*/32static long ima_key_queue_timeout = 300000; /* 5 Minutes */33static void ima_keys_handler(struct work_struct *work);34static DECLARE_DELAYED_WORK(ima_keys_delayed_work, ima_keys_handler);35static bool timer_expired;3637/*38* This worker function frees keys that may still be39* queued up in case custom IMA policy was not loaded.40*/41static void ima_keys_handler(struct work_struct *work)42{43timer_expired = true;44ima_process_queued_keys();45}4647/*48* This function sets up a worker to free queued keys in case49* custom IMA policy was never loaded.50*/51void ima_init_key_queue(void)52{53schedule_delayed_work(&ima_keys_delayed_work,54msecs_to_jiffies(ima_key_queue_timeout));55}5657static void ima_free_key_entry(struct ima_key_entry *entry)58{59if (entry) {60kfree(entry->payload);61kfree(entry->keyring_name);62kfree(entry);63}64}6566static struct ima_key_entry *ima_alloc_key_entry(struct key *keyring,67const void *payload,68size_t payload_len)69{70int rc = 0;71const char *audit_cause = "ENOMEM";72struct ima_key_entry *entry;7374entry = kzalloc(sizeof(*entry), GFP_KERNEL);75if (entry) {76entry->payload = kmemdup(payload, payload_len, GFP_KERNEL);77entry->keyring_name = kstrdup(keyring->description,78GFP_KERNEL);79entry->payload_len = payload_len;80}8182if ((entry == NULL) || (entry->payload == NULL) ||83(entry->keyring_name == NULL)) {84rc = -ENOMEM;85goto out;86}8788INIT_LIST_HEAD(&entry->list);8990out:91if (rc) {92integrity_audit_message(AUDIT_INTEGRITY_PCR, NULL,93keyring->description,94func_measure_str(KEY_CHECK),95audit_cause, rc, 0, rc);96ima_free_key_entry(entry);97entry = NULL;98}99100return entry;101}102103bool ima_queue_key(struct key *keyring, const void *payload,104size_t payload_len)105{106bool queued = false;107struct ima_key_entry *entry;108109entry = ima_alloc_key_entry(keyring, payload, payload_len);110if (!entry)111return false;112113mutex_lock(&ima_keys_lock);114if (!ima_process_keys) {115list_add_tail(&entry->list, &ima_keys);116queued = true;117}118mutex_unlock(&ima_keys_lock);119120if (!queued)121ima_free_key_entry(entry);122123return queued;124}125126/*127* ima_process_queued_keys() - process keys queued for measurement128*129* This function sets ima_process_keys to true and processes queued keys.130* From here on keys will be processed right away (not queued).131*/132void ima_process_queued_keys(void)133{134struct ima_key_entry *entry, *tmp;135bool process = false;136137if (ima_process_keys)138return;139140/*141* Since ima_process_keys is set to true, any new key will be142* processed immediately and not be queued to ima_keys list.143* First one setting the ima_process_keys flag to true will144* process the queued keys.145*/146mutex_lock(&ima_keys_lock);147if (!ima_process_keys) {148ima_process_keys = true;149process = true;150}151mutex_unlock(&ima_keys_lock);152153if (!process)154return;155156if (!timer_expired)157cancel_delayed_work_sync(&ima_keys_delayed_work);158159list_for_each_entry_safe(entry, tmp, &ima_keys, list) {160if (!timer_expired)161process_buffer_measurement(&nop_mnt_idmap, NULL,162entry->payload,163entry->payload_len,164entry->keyring_name,165KEY_CHECK, 0,166entry->keyring_name,167false, NULL, 0);168list_del(&entry->list);169ima_free_key_entry(entry);170}171}172173inline bool ima_should_queue_key(void)174{175return !ima_process_keys;176}177178179