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