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}
v4.17
  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.rst
 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 <linux/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_positive(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
123static void free_request_key_auth(struct request_key_auth *rka)
124{
125	if (!rka)
126		return;
127	key_put(rka->target_key);
128	key_put(rka->dest_keyring);
129	if (rka->cred)
130		put_cred(rka->cred);
131	kfree(rka->callout_info);
132	kfree(rka);
133}
134
135/*
136 * Destroy an instantiation authorisation token key.
137 */
138static void request_key_auth_destroy(struct key *key)
139{
140	struct request_key_auth *rka = key->payload.data[0];
141
142	kenter("{%d}", key->serial);
143
144	free_request_key_auth(rka);
 
 
 
 
 
 
 
 
145}
146
147/*
148 * Create an authorisation token for /sbin/request-key or whoever to gain
149 * access to the caller's security data.
150 */
151struct key *request_key_auth_new(struct key *target, const void *callout_info,
152				 size_t callout_len, struct key *dest_keyring)
153{
154	struct request_key_auth *rka, *irka;
155	const struct cred *cred = current->cred;
156	struct key *authkey = NULL;
157	char desc[20];
158	int ret = -ENOMEM;
159
160	kenter("%d,", target->serial);
161
162	/* allocate a auth record */
163	rka = kzalloc(sizeof(*rka), GFP_KERNEL);
164	if (!rka)
165		goto error;
166	rka->callout_info = kmemdup(callout_info, callout_len, GFP_KERNEL);
167	if (!rka->callout_info)
168		goto error_free_rka;
169	rka->callout_len = callout_len;
 
 
 
 
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,
180			     &cred->request_key_auth->flags)) {
181			up_read(&cred->request_key_auth->sem);
182			ret = -EKEYREVOKED;
183			goto error_free_rka;
184		}
185
186		irka = cred->request_key_auth->payload.data[0];
187		rka->cred = get_cred(irka->cred);
188		rka->pid = irka->pid;
189
190		up_read(&cred->request_key_auth->sem);
191	}
192	else {
193		/* it isn't - use this process as the context */
194		rka->cred = get_cred(cred);
195		rka->pid = current->pid;
196	}
197
198	rka->target_key = key_get(target);
199	rka->dest_keyring = key_get(dest_keyring);
 
 
200
201	/* allocate the auth key */
202	sprintf(desc, "%x", target->serial);
203
204	authkey = key_alloc(&key_type_request_key_auth, desc,
205			    cred->fsuid, cred->fsgid, cred,
206			    KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
207			    KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL);
208	if (IS_ERR(authkey)) {
209		ret = PTR_ERR(authkey);
210		goto error_free_rka;
211	}
212
213	/* construct the auth key */
214	ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
215	if (ret < 0)
216		goto error_put_authkey;
217
218	kleave(" = {%d,%d}", authkey->serial, refcount_read(&authkey->usage));
219	return authkey;
220
221error_put_authkey:
 
 
 
 
 
 
 
 
222	key_put(authkey);
223error_free_rka:
224	free_request_key_auth(rka);
225error:
 
 
226	kleave("= %d", ret);
227	return ERR_PTR(ret);
228}
229
230/*
231 * Search the current process's keyrings for the authorisation key for
232 * instantiation of a key.
233 */
234struct key *key_get_instantiation_authkey(key_serial_t target_id)
235{
236	char description[16];
237	struct keyring_search_context ctx = {
238		.index_key.type		= &key_type_request_key_auth,
239		.index_key.description	= description,
240		.cred			= current_cred(),
241		.match_data.cmp		= key_default_cmp,
242		.match_data.raw_data	= description,
243		.match_data.lookup_type	= KEYRING_SEARCH_LOOKUP_DIRECT,
244		.flags			= KEYRING_SEARCH_DO_STATE_CHECK,
245	};
246	struct key *authkey;
247	key_ref_t authkey_ref;
248
249	sprintf(description, "%x", target_id);
250
251	authkey_ref = search_process_keyrings(&ctx);
252
253	if (IS_ERR(authkey_ref)) {
254		authkey = ERR_CAST(authkey_ref);
255		if (authkey == ERR_PTR(-EAGAIN))
256			authkey = ERR_PTR(-ENOKEY);
257		goto error;
258	}
259
260	authkey = key_ref_to_ptr(authkey_ref);
261	if (test_bit(KEY_FLAG_REVOKED, &authkey->flags)) {
262		key_put(authkey);
263		authkey = ERR_PTR(-EKEYREVOKED);
264	}
265
266error:
267	return authkey;
268}