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 (dhowells@redhat.com)
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
18static int request_key_auth_preparse(struct key_preparsed_payload *);
19static void request_key_auth_free_preparse(struct key_preparsed_payload *);
20static int request_key_auth_instantiate(struct key *,
21					struct key_preparsed_payload *);
22static void request_key_auth_describe(const struct key *, struct seq_file *);
23static void request_key_auth_revoke(struct key *);
24static void request_key_auth_destroy(struct key *);
25static long request_key_auth_read(const struct key *, char *, size_t);
26
27/*
28 * The request-key authorisation key type definition.
29 */
30struct 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
42static int request_key_auth_preparse(struct key_preparsed_payload *prep)
43{
44	return 0;
45}
46
47static void request_key_auth_free_preparse(struct key_preparsed_payload *prep)
48{
49}
50
51/*
52 * Instantiate a request-key authorisation key.
53 */
54static 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 */
64static 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 */
82static 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
106static 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 */
121static 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 */
134static 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 */
146static 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 */
161struct 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
233error_put_authkey:
234	key_put(authkey);
235error_free_rka:
236	free_request_key_auth(rka);
237error:
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 */
246struct 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
281error:
282	return authkey;
283}
284