Linux Audio

Check our new training course

Loading...
v5.9
  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	strlcpy(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}
v3.1
 
  1/* Request key authorisation token key definition.
  2 *
  3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
  4 * Written by David Howells (dhowells@redhat.com)
  5 *
  6 * This program is free software; you can redistribute it and/or
  7 * modify it under the terms of the GNU General Public License
  8 * as published by the Free Software Foundation; either version
  9 * 2 of the License, or (at your option) any later version.
 10 *
 11 * See Documentation/security/keys-request-key.txt
 12 */
 13
 14#include <linux/module.h>
 15#include <linux/sched.h>
 16#include <linux/err.h>
 17#include <linux/seq_file.h>
 18#include <linux/slab.h>
 19#include <asm/uaccess.h>
 20#include "internal.h"
 
 21
 22static int request_key_auth_instantiate(struct key *, const void *, size_t);
 
 
 
 23static void request_key_auth_describe(const struct key *, struct seq_file *);
 24static void request_key_auth_revoke(struct key *);
 25static void request_key_auth_destroy(struct key *);
 26static long request_key_auth_read(const struct key *, char __user *, size_t);
 27
 28/*
 29 * The request-key authorisation key type definition.
 30 */
 31struct key_type key_type_request_key_auth = {
 32	.name		= ".request_key_auth",
 33	.def_datalen	= sizeof(struct request_key_auth),
 
 
 34	.instantiate	= request_key_auth_instantiate,
 35	.describe	= request_key_auth_describe,
 36	.revoke		= request_key_auth_revoke,
 37	.destroy	= request_key_auth_destroy,
 38	.read		= request_key_auth_read,
 39};
 40
 
 
 
 
 
 
 
 
 
 41/*
 42 * Instantiate a request-key authorisation key.
 43 */
 44static int request_key_auth_instantiate(struct key *key,
 45					const void *data,
 46					size_t datalen)
 47{
 48	key->payload.data = (struct request_key_auth *) data;
 49	return 0;
 50}
 51
 52/*
 53 * Describe an authorisation token.
 54 */
 55static void request_key_auth_describe(const struct key *key,
 56				      struct seq_file *m)
 57{
 58	struct request_key_auth *rka = key->payload.data;
 
 
 
 59
 60	seq_puts(m, "key:");
 61	seq_puts(m, key->description);
 62	if (key_is_instantiated(key))
 63		seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
 64}
 65
 66/*
 67 * Read the callout_info data (retrieves the callout information).
 68 * - the key's semaphore is read-locked
 69 */
 70static long request_key_auth_read(const struct key *key,
 71				  char __user *buffer, size_t buflen)
 72{
 73	struct request_key_auth *rka = key->payload.data;
 74	size_t datalen;
 75	long ret;
 76
 
 
 
 77	datalen = rka->callout_len;
 78	ret = datalen;
 79
 80	/* we can return the data as is */
 81	if (buffer && buflen > 0) {
 82		if (buflen > datalen)
 83			buflen = datalen;
 84
 85		if (copy_to_user(buffer, rka->callout_info, buflen) != 0)
 86			ret = -EFAULT;
 87	}
 88
 89	return ret;
 90}
 91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 92/*
 93 * Handle revocation of an authorisation token key.
 94 *
 95 * Called with the key sem write-locked.
 96 */
 97static void request_key_auth_revoke(struct key *key)
 98{
 99	struct request_key_auth *rka = key->payload.data;
100
101	kenter("{%d}", key->serial);
102
103	if (rka->cred) {
104		put_cred(rka->cred);
105		rka->cred = NULL;
106	}
107}
108
109/*
110 * Destroy an instantiation authorisation token key.
111 */
112static void request_key_auth_destroy(struct key *key)
113{
114	struct request_key_auth *rka = key->payload.data;
115
116	kenter("{%d}", key->serial);
117
118	if (rka->cred) {
119		put_cred(rka->cred);
120		rka->cred = NULL;
121	}
122
123	key_put(rka->target_key);
124	key_put(rka->dest_keyring);
125	kfree(rka->callout_info);
126	kfree(rka);
127}
128
129/*
130 * Create an authorisation token for /sbin/request-key or whoever to gain
131 * access to the caller's security data.
132 */
133struct key *request_key_auth_new(struct key *target, const void *callout_info,
134				 size_t callout_len, struct key *dest_keyring)
 
135{
136	struct request_key_auth *rka, *irka;
137	const struct cred *cred = current->cred;
138	struct key *authkey = NULL;
139	char desc[20];
140	int ret;
141
142	kenter("%d,", target->serial);
143
144	/* allocate a auth record */
145	rka = kmalloc(sizeof(*rka), GFP_KERNEL);
146	if (!rka) {
147		kleave(" = -ENOMEM");
148		return ERR_PTR(-ENOMEM);
149	}
150	rka->callout_info = kmalloc(callout_len, GFP_KERNEL);
151	if (!rka->callout_info) {
152		kleave(" = -ENOMEM");
153		kfree(rka);
154		return ERR_PTR(-ENOMEM);
155	}
156
157	/* see if the calling process is already servicing the key request of
158	 * another process */
159	if (cred->request_key_auth) {
160		/* it is - use that instantiation context here too */
161		down_read(&cred->request_key_auth->sem);
162
163		/* if the auth key has been revoked, then the key we're
164		 * servicing is already instantiated */
165		if (test_bit(KEY_FLAG_REVOKED, &cred->request_key_auth->flags))
166			goto auth_key_revoked;
 
 
 
 
167
168		irka = cred->request_key_auth->payload.data;
169		rka->cred = get_cred(irka->cred);
170		rka->pid = irka->pid;
171
172		up_read(&cred->request_key_auth->sem);
173	}
174	else {
175		/* it isn't - use this process as the context */
176		rka->cred = get_cred(cred);
177		rka->pid = current->pid;
178	}
179
180	rka->target_key = key_get(target);
181	rka->dest_keyring = key_get(dest_keyring);
182	memcpy(rka->callout_info, callout_info, callout_len);
183	rka->callout_len = callout_len;
184
185	/* allocate the auth key */
186	sprintf(desc, "%x", target->serial);
187
188	authkey = key_alloc(&key_type_request_key_auth, desc,
189			    cred->fsuid, cred->fsgid, cred,
190			    KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
191			    KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA);
192	if (IS_ERR(authkey)) {
193		ret = PTR_ERR(authkey);
194		goto error_alloc;
195	}
196
197	/* construct the auth key */
198	ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
199	if (ret < 0)
200		goto error_inst;
201
202	kleave(" = {%d,%d}", authkey->serial, atomic_read(&authkey->usage));
203	return authkey;
204
205auth_key_revoked:
206	up_read(&cred->request_key_auth->sem);
207	kfree(rka->callout_info);
208	kfree(rka);
209	kleave("= -EKEYREVOKED");
210	return ERR_PTR(-EKEYREVOKED);
211
212error_inst:
213	key_revoke(authkey);
214	key_put(authkey);
215error_alloc:
216	key_put(rka->target_key);
217	key_put(rka->dest_keyring);
218	kfree(rka->callout_info);
219	kfree(rka);
220	kleave("= %d", ret);
221	return ERR_PTR(ret);
222}
223
224/*
225 * See if an authorisation key is associated with a particular key.
226 */
227static int key_get_instantiation_authkey_match(const struct key *key,
228					       const void *_id)
229{
230	struct request_key_auth *rka = key->payload.data;
231	key_serial_t id = (key_serial_t)(unsigned long) _id;
232
233	return rka->target_key->serial == id;
234}
235
236/*
237 * Search the current process's keyrings for the authorisation key for
238 * instantiation of a key.
239 */
240struct key *key_get_instantiation_authkey(key_serial_t target_id)
241{
242	const struct cred *cred = current_cred();
 
 
 
 
 
 
 
 
 
 
243	struct key *authkey;
244	key_ref_t authkey_ref;
245
246	authkey_ref = search_process_keyrings(
247		&key_type_request_key_auth,
248		(void *) (unsigned long) target_id,
249		key_get_instantiation_authkey_match,
250		cred);
251
252	if (IS_ERR(authkey_ref)) {
253		authkey = ERR_CAST(authkey_ref);
254		if (authkey == ERR_PTR(-EAGAIN))
255			authkey = ERR_PTR(-ENOKEY);
256		goto error;
257	}
258
259	authkey = key_ref_to_ptr(authkey_ref);
260	if (test_bit(KEY_FLAG_REVOKED, &authkey->flags)) {
261		key_put(authkey);
262		authkey = ERR_PTR(-EKEYREVOKED);
263	}
264
265error:
266	return authkey;
267}