Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/security/integrity/ima/ima_queue_keys.c
26424 views
1
// SPDX-License-Identifier: GPL-2.0+
2
/*
3
* Copyright (C) 2019 Microsoft Corporation
4
*
5
* Author: Lakshmi Ramasubramanian ([email protected])
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
*/
20
static bool ima_process_keys;
21
22
/*
23
* To synchronize access to the list of keys that need to be measured
24
*/
25
static DEFINE_MUTEX(ima_keys_lock);
26
static 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
*/
33
static long ima_key_queue_timeout = 300000; /* 5 Minutes */
34
static void ima_keys_handler(struct work_struct *work);
35
static DECLARE_DELAYED_WORK(ima_keys_delayed_work, ima_keys_handler);
36
static 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
*/
42
static 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
*/
52
void ima_init_key_queue(void)
53
{
54
schedule_delayed_work(&ima_keys_delayed_work,
55
msecs_to_jiffies(ima_key_queue_timeout));
56
}
57
58
static 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
67
static 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
91
out:
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
104
bool 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
*/
133
void 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(&nop_mnt_idmap, 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
174
inline bool ima_should_queue_key(void)
175
{
176
return !ima_process_keys;
177
}
178
179