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}
v3.5.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
 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}