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