Linux Audio

Check our new training course

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