ima_queue_keys.c (4120B)
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2019 Microsoft Corporation 4 * 5 * Author: Lakshmi Ramasubramanian (nramas@linux.microsoft.com) 6 * 7 * File: ima_queue_keys.c 8 * Enables deferred processing of keys 9 */ 10 11#include <linux/user_namespace.h> 12#include <linux/workqueue.h> 13#include <keys/asymmetric-type.h> 14#include "ima.h" 15 16/* 17 * Flag to indicate whether a key can be processed 18 * right away or should be queued for processing later. 19 */ 20static bool ima_process_keys; 21 22/* 23 * To synchronize access to the list of keys that need to be measured 24 */ 25static DEFINE_MUTEX(ima_keys_lock); 26static LIST_HEAD(ima_keys); 27 28/* 29 * If custom IMA policy is not loaded then keys queued up 30 * for measurement should be freed. This worker is used 31 * for handling this scenario. 32 */ 33static long ima_key_queue_timeout = 300000; /* 5 Minutes */ 34static void ima_keys_handler(struct work_struct *work); 35static DECLARE_DELAYED_WORK(ima_keys_delayed_work, ima_keys_handler); 36static bool timer_expired; 37 38/* 39 * This worker function frees keys that may still be 40 * queued up in case custom IMA policy was not loaded. 41 */ 42static void ima_keys_handler(struct work_struct *work) 43{ 44 timer_expired = true; 45 ima_process_queued_keys(); 46} 47 48/* 49 * This function sets up a worker to free queued keys in case 50 * custom IMA policy was never loaded. 51 */ 52void ima_init_key_queue(void) 53{ 54 schedule_delayed_work(&ima_keys_delayed_work, 55 msecs_to_jiffies(ima_key_queue_timeout)); 56} 57 58static void ima_free_key_entry(struct ima_key_entry *entry) 59{ 60 if (entry) { 61 kfree(entry->payload); 62 kfree(entry->keyring_name); 63 kfree(entry); 64 } 65} 66 67static struct ima_key_entry *ima_alloc_key_entry(struct key *keyring, 68 const void *payload, 69 size_t payload_len) 70{ 71 int rc = 0; 72 const char *audit_cause = "ENOMEM"; 73 struct ima_key_entry *entry; 74 75 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 76 if (entry) { 77 entry->payload = kmemdup(payload, payload_len, GFP_KERNEL); 78 entry->keyring_name = kstrdup(keyring->description, 79 GFP_KERNEL); 80 entry->payload_len = payload_len; 81 } 82 83 if ((entry == NULL) || (entry->payload == NULL) || 84 (entry->keyring_name == NULL)) { 85 rc = -ENOMEM; 86 goto out; 87 } 88 89 INIT_LIST_HEAD(&entry->list); 90 91out: 92 if (rc) { 93 integrity_audit_message(AUDIT_INTEGRITY_PCR, NULL, 94 keyring->description, 95 func_measure_str(KEY_CHECK), 96 audit_cause, rc, 0, rc); 97 ima_free_key_entry(entry); 98 entry = NULL; 99 } 100 101 return entry; 102} 103 104bool ima_queue_key(struct key *keyring, const void *payload, 105 size_t payload_len) 106{ 107 bool queued = false; 108 struct ima_key_entry *entry; 109 110 entry = ima_alloc_key_entry(keyring, payload, payload_len); 111 if (!entry) 112 return false; 113 114 mutex_lock(&ima_keys_lock); 115 if (!ima_process_keys) { 116 list_add_tail(&entry->list, &ima_keys); 117 queued = true; 118 } 119 mutex_unlock(&ima_keys_lock); 120 121 if (!queued) 122 ima_free_key_entry(entry); 123 124 return queued; 125} 126 127/* 128 * ima_process_queued_keys() - process keys queued for measurement 129 * 130 * This function sets ima_process_keys to true and processes queued keys. 131 * From here on keys will be processed right away (not queued). 132 */ 133void ima_process_queued_keys(void) 134{ 135 struct ima_key_entry *entry, *tmp; 136 bool process = false; 137 138 if (ima_process_keys) 139 return; 140 141 /* 142 * Since ima_process_keys is set to true, any new key will be 143 * processed immediately and not be queued to ima_keys list. 144 * First one setting the ima_process_keys flag to true will 145 * process the queued keys. 146 */ 147 mutex_lock(&ima_keys_lock); 148 if (!ima_process_keys) { 149 ima_process_keys = true; 150 process = true; 151 } 152 mutex_unlock(&ima_keys_lock); 153 154 if (!process) 155 return; 156 157 if (!timer_expired) 158 cancel_delayed_work_sync(&ima_keys_delayed_work); 159 160 list_for_each_entry_safe(entry, tmp, &ima_keys, list) { 161 if (!timer_expired) 162 process_buffer_measurement(&init_user_ns, NULL, 163 entry->payload, 164 entry->payload_len, 165 entry->keyring_name, 166 KEY_CHECK, 0, 167 entry->keyring_name, 168 false, NULL, 0); 169 list_del(&entry->list); 170 ima_free_key_entry(entry); 171 } 172} 173 174inline bool ima_should_queue_key(void) 175{ 176 return !ima_process_keys; 177}