Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/security/keys/request_key_auth.c
26378 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/* Request key authorisation token key definition.
3
*
4
* Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
5
* Written by David Howells ([email protected])
6
*
7
* See Documentation/security/keys/request-key.rst
8
*/
9
10
#include <linux/sched.h>
11
#include <linux/err.h>
12
#include <linux/seq_file.h>
13
#include <linux/slab.h>
14
#include <linux/uaccess.h>
15
#include "internal.h"
16
#include <keys/request_key_auth-type.h>
17
18
static int request_key_auth_preparse(struct key_preparsed_payload *);
19
static void request_key_auth_free_preparse(struct key_preparsed_payload *);
20
static int request_key_auth_instantiate(struct key *,
21
struct key_preparsed_payload *);
22
static void request_key_auth_describe(const struct key *, struct seq_file *);
23
static void request_key_auth_revoke(struct key *);
24
static void request_key_auth_destroy(struct key *);
25
static long request_key_auth_read(const struct key *, char *, size_t);
26
27
/*
28
* The request-key authorisation key type definition.
29
*/
30
struct key_type key_type_request_key_auth = {
31
.name = ".request_key_auth",
32
.def_datalen = sizeof(struct request_key_auth),
33
.preparse = request_key_auth_preparse,
34
.free_preparse = request_key_auth_free_preparse,
35
.instantiate = request_key_auth_instantiate,
36
.describe = request_key_auth_describe,
37
.revoke = request_key_auth_revoke,
38
.destroy = request_key_auth_destroy,
39
.read = request_key_auth_read,
40
};
41
42
static int request_key_auth_preparse(struct key_preparsed_payload *prep)
43
{
44
return 0;
45
}
46
47
static void request_key_auth_free_preparse(struct key_preparsed_payload *prep)
48
{
49
}
50
51
/*
52
* Instantiate a request-key authorisation key.
53
*/
54
static int request_key_auth_instantiate(struct key *key,
55
struct key_preparsed_payload *prep)
56
{
57
rcu_assign_keypointer(key, (struct request_key_auth *)prep->data);
58
return 0;
59
}
60
61
/*
62
* Describe an authorisation token.
63
*/
64
static void request_key_auth_describe(const struct key *key,
65
struct seq_file *m)
66
{
67
struct request_key_auth *rka = dereference_key_rcu(key);
68
69
if (!rka)
70
return;
71
72
seq_puts(m, "key:");
73
seq_puts(m, key->description);
74
if (key_is_positive(key))
75
seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
76
}
77
78
/*
79
* Read the callout_info data (retrieves the callout information).
80
* - the key's semaphore is read-locked
81
*/
82
static long request_key_auth_read(const struct key *key,
83
char *buffer, size_t buflen)
84
{
85
struct request_key_auth *rka = dereference_key_locked(key);
86
size_t datalen;
87
long ret;
88
89
if (!rka)
90
return -EKEYREVOKED;
91
92
datalen = rka->callout_len;
93
ret = datalen;
94
95
/* we can return the data as is */
96
if (buffer && buflen > 0) {
97
if (buflen > datalen)
98
buflen = datalen;
99
100
memcpy(buffer, rka->callout_info, buflen);
101
}
102
103
return ret;
104
}
105
106
static void free_request_key_auth(struct request_key_auth *rka)
107
{
108
if (!rka)
109
return;
110
key_put(rka->target_key);
111
key_put(rka->dest_keyring);
112
if (rka->cred)
113
put_cred(rka->cred);
114
kfree(rka->callout_info);
115
kfree(rka);
116
}
117
118
/*
119
* Dispose of the request_key_auth record under RCU conditions
120
*/
121
static void request_key_auth_rcu_disposal(struct rcu_head *rcu)
122
{
123
struct request_key_auth *rka =
124
container_of(rcu, struct request_key_auth, rcu);
125
126
free_request_key_auth(rka);
127
}
128
129
/*
130
* Handle revocation of an authorisation token key.
131
*
132
* Called with the key sem write-locked.
133
*/
134
static void request_key_auth_revoke(struct key *key)
135
{
136
struct request_key_auth *rka = dereference_key_locked(key);
137
138
kenter("{%d}", key->serial);
139
rcu_assign_keypointer(key, NULL);
140
call_rcu(&rka->rcu, request_key_auth_rcu_disposal);
141
}
142
143
/*
144
* Destroy an instantiation authorisation token key.
145
*/
146
static void request_key_auth_destroy(struct key *key)
147
{
148
struct request_key_auth *rka = rcu_access_pointer(key->payload.rcu_data0);
149
150
kenter("{%d}", key->serial);
151
if (rka) {
152
rcu_assign_keypointer(key, NULL);
153
call_rcu(&rka->rcu, request_key_auth_rcu_disposal);
154
}
155
}
156
157
/*
158
* Create an authorisation token for /sbin/request-key or whoever to gain
159
* access to the caller's security data.
160
*/
161
struct key *request_key_auth_new(struct key *target, const char *op,
162
const void *callout_info, size_t callout_len,
163
struct key *dest_keyring)
164
{
165
struct request_key_auth *rka, *irka;
166
const struct cred *cred = current_cred();
167
struct key *authkey = NULL;
168
char desc[20];
169
int ret = -ENOMEM;
170
171
kenter("%d,", target->serial);
172
173
/* allocate a auth record */
174
rka = kzalloc(sizeof(*rka), GFP_KERNEL);
175
if (!rka)
176
goto error;
177
rka->callout_info = kmemdup(callout_info, callout_len, GFP_KERNEL);
178
if (!rka->callout_info)
179
goto error_free_rka;
180
rka->callout_len = callout_len;
181
strscpy(rka->op, op, sizeof(rka->op));
182
183
/* see if the calling process is already servicing the key request of
184
* another process */
185
if (cred->request_key_auth) {
186
/* it is - use that instantiation context here too */
187
down_read(&cred->request_key_auth->sem);
188
189
/* if the auth key has been revoked, then the key we're
190
* servicing is already instantiated */
191
if (test_bit(KEY_FLAG_REVOKED,
192
&cred->request_key_auth->flags)) {
193
up_read(&cred->request_key_auth->sem);
194
ret = -EKEYREVOKED;
195
goto error_free_rka;
196
}
197
198
irka = cred->request_key_auth->payload.data[0];
199
rka->cred = get_cred(irka->cred);
200
rka->pid = irka->pid;
201
202
up_read(&cred->request_key_auth->sem);
203
}
204
else {
205
/* it isn't - use this process as the context */
206
rka->cred = get_cred(cred);
207
rka->pid = current->pid;
208
}
209
210
rka->target_key = key_get(target);
211
rka->dest_keyring = key_get(dest_keyring);
212
213
/* allocate the auth key */
214
sprintf(desc, "%x", target->serial);
215
216
authkey = key_alloc(&key_type_request_key_auth, desc,
217
cred->fsuid, cred->fsgid, cred,
218
KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | KEY_POS_LINK |
219
KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL);
220
if (IS_ERR(authkey)) {
221
ret = PTR_ERR(authkey);
222
goto error_free_rka;
223
}
224
225
/* construct the auth key */
226
ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
227
if (ret < 0)
228
goto error_put_authkey;
229
230
kleave(" = {%d,%d}", authkey->serial, refcount_read(&authkey->usage));
231
return authkey;
232
233
error_put_authkey:
234
key_put(authkey);
235
error_free_rka:
236
free_request_key_auth(rka);
237
error:
238
kleave("= %d", ret);
239
return ERR_PTR(ret);
240
}
241
242
/*
243
* Search the current process's keyrings for the authorisation key for
244
* instantiation of a key.
245
*/
246
struct key *key_get_instantiation_authkey(key_serial_t target_id)
247
{
248
char description[16];
249
struct keyring_search_context ctx = {
250
.index_key.type = &key_type_request_key_auth,
251
.index_key.description = description,
252
.cred = current_cred(),
253
.match_data.cmp = key_default_cmp,
254
.match_data.raw_data = description,
255
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
256
.flags = (KEYRING_SEARCH_DO_STATE_CHECK |
257
KEYRING_SEARCH_RECURSE),
258
};
259
struct key *authkey;
260
key_ref_t authkey_ref;
261
262
ctx.index_key.desc_len = sprintf(description, "%x", target_id);
263
264
rcu_read_lock();
265
authkey_ref = search_process_keyrings_rcu(&ctx);
266
rcu_read_unlock();
267
268
if (IS_ERR(authkey_ref)) {
269
authkey = ERR_CAST(authkey_ref);
270
if (authkey == ERR_PTR(-EAGAIN))
271
authkey = ERR_PTR(-ENOKEY);
272
goto error;
273
}
274
275
authkey = key_ref_to_ptr(authkey_ref);
276
if (test_bit(KEY_FLAG_REVOKED, &authkey->flags)) {
277
key_put(authkey);
278
authkey = ERR_PTR(-EKEYREVOKED);
279
}
280
281
error:
282
return authkey;
283
}
284
285