Blame view

security/keys/request_key.c 12.8 KB
76181c134   David Howells   KEYS: Make reques...
1
  /* Request a key from userspace
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
   *
76181c134   David Howells   KEYS: Make reques...
3
   * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
5
6
7
8
9
   * Written by David Howells (dhowells@redhat.com)
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version
   * 2 of the License, or (at your option) any later version.
f1a9badcf   David Howells   [PATCH] Keys: Add...
10
11
   *
   * See Documentation/keys-request-key.txt
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
14
15
16
17
   */
  
  #include <linux/module.h>
  #include <linux/sched.h>
  #include <linux/kmod.h>
  #include <linux/err.h>
3e30148c3   David Howells   [PATCH] Keys: Mak...
18
  #include <linux/keyctl.h>
fdb89bce6   Robert P. J. Day   keys: explicitly ...
19
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
  #include "internal.h"
76181c134   David Howells   KEYS: Make reques...
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  /*
   * wait_on_bit() sleep function for uninterruptible waiting
   */
  static int key_wait_bit(void *flags)
  {
  	schedule();
  	return 0;
  }
  
  /*
   * wait_on_bit() sleep function for interruptible waiting
   */
  static int key_wait_bit_intr(void *flags)
  {
  	schedule();
  	return signal_pending(current) ? -ERESTARTSYS : 0;
  }
  
  /*
   * call to complete the construction of a key
   */
  void complete_request_key(struct key_construction *cons, int error)
  {
  	kenter("{%d,%d},%d", cons->key->serial, cons->authkey->serial, error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45

76181c134   David Howells   KEYS: Make reques...
46
47
48
49
50
51
52
53
54
55
56
  	if (error < 0)
  		key_negate_and_link(cons->key, key_negative_timeout, NULL,
  				    cons->authkey);
  	else
  		key_revoke(cons->authkey);
  
  	key_put(cons->key);
  	key_put(cons->authkey);
  	kfree(cons);
  }
  EXPORT_SYMBOL(complete_request_key);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
59
  /*
   * request userspace finish the construction of a key
b5f545c88   David Howells   [PATCH] keys: Per...
60
   * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
   */
76181c134   David Howells   KEYS: Make reques...
62
  static int call_sbin_request_key(struct key_construction *cons,
4e54f0854   David Howells   [PATCH] Keys: All...
63
64
  				 const char *op,
  				 void *aux)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
66
  {
  	struct task_struct *tsk = current;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
  	key_serial_t prkey, sskey;
76181c134   David Howells   KEYS: Make reques...
68
  	struct key *key = cons->key, *authkey = cons->authkey, *keyring;
b5f545c88   David Howells   [PATCH] keys: Per...
69
  	char *argv[9], *envp[3], uid_str[12], gid_str[12];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
  	char key_str[12], keyring_str[3][12];
b5f545c88   David Howells   [PATCH] keys: Per...
71
  	char desc[20];
3e30148c3   David Howells   [PATCH] Keys: Mak...
72
  	int ret, i;
b5f545c88   David Howells   [PATCH] keys: Per...
73
  	kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
3e30148c3   David Howells   [PATCH] Keys: Mak...
74

b5f545c88   David Howells   [PATCH] keys: Per...
75
76
  	/* allocate a new session keyring */
  	sprintf(desc, "_req.%u", key->serial);
7e047ef5f   David Howells   [PATCH] keys: sor...
77
78
  	keyring = keyring_alloc(desc, current->fsuid, current->fsgid, current,
  				KEY_ALLOC_QUOTA_OVERRUN, NULL);
b5f545c88   David Howells   [PATCH] keys: Per...
79
80
81
  	if (IS_ERR(keyring)) {
  		ret = PTR_ERR(keyring);
  		goto error_alloc;
3e30148c3   David Howells   [PATCH] Keys: Mak...
82
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83

b5f545c88   David Howells   [PATCH] keys: Per...
84
85
86
87
  	/* attach the auth key to the session keyring */
  	ret = __key_link(keyring, authkey);
  	if (ret < 0)
  		goto error_link;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
90
91
92
93
94
95
96
97
98
99
100
101
  	/* record the UID and GID */
  	sprintf(uid_str, "%d", current->fsuid);
  	sprintf(gid_str, "%d", current->fsgid);
  
  	/* we say which key is under construction */
  	sprintf(key_str, "%d", key->serial);
  
  	/* we specify the process's default keyrings */
  	sprintf(keyring_str[0], "%d",
  		tsk->thread_keyring ? tsk->thread_keyring->serial : 0);
  
  	prkey = 0;
  	if (tsk->signal->process_keyring)
  		prkey = tsk->signal->process_keyring->serial;
3e30148c3   David Howells   [PATCH] Keys: Mak...
102
  	sprintf(keyring_str[1], "%d", prkey);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103

3e30148c3   David Howells   [PATCH] Keys: Mak...
104
105
106
107
  	if (tsk->signal->session_keyring) {
  		rcu_read_lock();
  		sskey = rcu_dereference(tsk->signal->session_keyring)->serial;
  		rcu_read_unlock();
76181c134   David Howells   KEYS: Make reques...
108
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109
  		sskey = tsk->user->session_keyring->serial;
3e30148c3   David Howells   [PATCH] Keys: Mak...
110
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
  	sprintf(keyring_str[2], "%d", sskey);
  
  	/* set up a minimal environment */
  	i = 0;
  	envp[i++] = "HOME=/";
  	envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
  	envp[i] = NULL;
  
  	/* set up the argument list */
  	i = 0;
  	argv[i++] = "/sbin/request-key";
  	argv[i++] = (char *) op;
  	argv[i++] = key_str;
  	argv[i++] = uid_str;
  	argv[i++] = gid_str;
  	argv[i++] = keyring_str[0];
  	argv[i++] = keyring_str[1];
  	argv[i++] = keyring_str[2];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
131
132
  	argv[i] = NULL;
  
  	/* do it */
86313c488   Jeremy Fitzhardinge   usermodehelper: T...
133
134
  	ret = call_usermodehelper_keys(argv[0], argv, envp, keyring,
  				       UMH_WAIT_PROC);
76181c134   David Howells   KEYS: Make reques...
135
136
137
138
139
140
141
142
143
144
145
  	kdebug("usermode -> 0x%x", ret);
  	if (ret >= 0) {
  		/* ret is the exit/wait code */
  		if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags) ||
  		    key_validate(key) < 0)
  			ret = -ENOKEY;
  		else
  			/* ignore any errors from userspace if the key was
  			 * instantiated */
  			ret = 0;
  	}
3e30148c3   David Howells   [PATCH] Keys: Mak...
146

b5f545c88   David Howells   [PATCH] keys: Per...
147
148
  error_link:
  	key_put(keyring);
3e30148c3   David Howells   [PATCH] Keys: Mak...
149

b5f545c88   David Howells   [PATCH] keys: Per...
150
  error_alloc:
3e30148c3   David Howells   [PATCH] Keys: Mak...
151
  	kleave(" = %d", ret);
76181c134   David Howells   KEYS: Make reques...
152
  	complete_request_key(cons, ret);
3e30148c3   David Howells   [PATCH] Keys: Mak...
153
  	return ret;
76181c134   David Howells   KEYS: Make reques...
154
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
  /*
76181c134   David Howells   KEYS: Make reques...
157
   * call out to userspace for key construction
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
159
   * - we ignore program failure and go on key status instead
   */
4a38e122e   David Howells   keys: allow the c...
160
161
  static int construct_key(struct key *key, const void *callout_info,
  			 size_t callout_len, void *aux)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
  {
76181c134   David Howells   KEYS: Make reques...
163
  	struct key_construction *cons;
b5f545c88   David Howells   [PATCH] keys: Per...
164
  	request_key_actor_t actor;
76181c134   David Howells   KEYS: Make reques...
165
166
  	struct key *authkey;
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167

4a38e122e   David Howells   keys: allow the c...
168
  	kenter("%d,%p,%zu,%p", key->serial, callout_info, callout_len, aux);
3e30148c3   David Howells   [PATCH] Keys: Mak...
169

76181c134   David Howells   KEYS: Make reques...
170
171
172
  	cons = kmalloc(sizeof(*cons), GFP_KERNEL);
  	if (!cons)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173

b5f545c88   David Howells   [PATCH] keys: Per...
174
  	/* allocate an authorisation key */
4a38e122e   David Howells   keys: allow the c...
175
  	authkey = request_key_auth_new(key, callout_info, callout_len);
b5f545c88   David Howells   [PATCH] keys: Per...
176
  	if (IS_ERR(authkey)) {
76181c134   David Howells   KEYS: Make reques...
177
  		kfree(cons);
b5f545c88   David Howells   [PATCH] keys: Per...
178
179
  		ret = PTR_ERR(authkey);
  		authkey = NULL;
76181c134   David Howells   KEYS: Make reques...
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  	} else {
  		cons->authkey = key_get(authkey);
  		cons->key = key_get(key);
  
  		/* make the call */
  		actor = call_sbin_request_key;
  		if (key->type->request_key)
  			actor = key->type->request_key;
  
  		ret = actor(cons, "create", aux);
  
  		/* check that the actor called complete_request_key() prior to
  		 * returning an error */
  		WARN_ON(ret < 0 &&
  			!test_bit(KEY_FLAG_REVOKED, &authkey->flags));
  		key_put(authkey);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
196
  	}
76181c134   David Howells   KEYS: Make reques...
197
198
199
  	kleave(" = %d", ret);
  	return ret;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
  /*
76181c134   David Howells   KEYS: Make reques...
202
203
   * link a key to the appropriate destination keyring
   * - the caller must hold a write lock on the destination keyring
3e30148c3   David Howells   [PATCH] Keys: Mak...
204
   */
76181c134   David Howells   KEYS: Make reques...
205
  static void construct_key_make_link(struct key *key, struct key *dest_keyring)
3e30148c3   David Howells   [PATCH] Keys: Mak...
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
  {
  	struct task_struct *tsk = current;
  	struct key *drop = NULL;
  
  	kenter("{%d},%p", key->serial, dest_keyring);
  
  	/* find the appropriate keyring */
  	if (!dest_keyring) {
  		switch (tsk->jit_keyring) {
  		case KEY_REQKEY_DEFL_DEFAULT:
  		case KEY_REQKEY_DEFL_THREAD_KEYRING:
  			dest_keyring = tsk->thread_keyring;
  			if (dest_keyring)
  				break;
  
  		case KEY_REQKEY_DEFL_PROCESS_KEYRING:
  			dest_keyring = tsk->signal->process_keyring;
  			if (dest_keyring)
  				break;
  
  		case KEY_REQKEY_DEFL_SESSION_KEYRING:
  			rcu_read_lock();
  			dest_keyring = key_get(
  				rcu_dereference(tsk->signal->session_keyring));
  			rcu_read_unlock();
  			drop = dest_keyring;
  
  			if (dest_keyring)
  				break;
  
  		case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
76181c134   David Howells   KEYS: Make reques...
237
  			dest_keyring = tsk->user->session_keyring;
3e30148c3   David Howells   [PATCH] Keys: Mak...
238
239
240
  			break;
  
  		case KEY_REQKEY_DEFL_USER_KEYRING:
76181c134   David Howells   KEYS: Make reques...
241
  			dest_keyring = tsk->user->uid_keyring;
3e30148c3   David Howells   [PATCH] Keys: Mak...
242
243
244
245
246
247
248
249
250
  			break;
  
  		case KEY_REQKEY_DEFL_GROUP_KEYRING:
  		default:
  			BUG();
  		}
  	}
  
  	/* and attach the key to it */
76181c134   David Howells   KEYS: Make reques...
251
  	__key_link(dest_keyring, key);
3e30148c3   David Howells   [PATCH] Keys: Mak...
252
  	key_put(drop);
3e30148c3   David Howells   [PATCH] Keys: Mak...
253
  	kleave("");
76181c134   David Howells   KEYS: Make reques...
254
  }
3e30148c3   David Howells   [PATCH] Keys: Mak...
255

76181c134   David Howells   KEYS: Make reques...
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
  /*
   * allocate a new key in under-construction state and attempt to link it in to
   * the requested place
   * - may return a key that's already under construction instead
   */
  static int construct_alloc_key(struct key_type *type,
  			       const char *description,
  			       struct key *dest_keyring,
  			       unsigned long flags,
  			       struct key_user *user,
  			       struct key **_key)
  {
  	struct key *key;
  	key_ref_t key_ref;
  
  	kenter("%s,%s,,,", type->name, description);
  
  	mutex_lock(&user->cons_lock);
  
  	key = key_alloc(type, description,
  			current->fsuid, current->fsgid, current, KEY_POS_ALL,
  			flags);
  	if (IS_ERR(key))
  		goto alloc_failed;
  
  	set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
  
  	if (dest_keyring)
  		down_write(&dest_keyring->sem);
  
  	/* attach the key to the destination keyring under lock, but we do need
  	 * to do another check just in case someone beat us to it whilst we
  	 * waited for locks */
  	mutex_lock(&key_construction_mutex);
  
  	key_ref = search_process_keyrings(type, description, type->match,
  					  current);
  	if (!IS_ERR(key_ref))
  		goto key_already_present;
  
  	if (dest_keyring)
  		construct_key_make_link(key, dest_keyring);
  
  	mutex_unlock(&key_construction_mutex);
  	if (dest_keyring)
  		up_write(&dest_keyring->sem);
  	mutex_unlock(&user->cons_lock);
  	*_key = key;
  	kleave(" = 0 [%d]", key_serial(key));
  	return 0;
  
  key_already_present:
  	mutex_unlock(&key_construction_mutex);
  	if (dest_keyring)
  		up_write(&dest_keyring->sem);
  	mutex_unlock(&user->cons_lock);
  	key_put(key);
  	*_key = key = key_ref_to_ptr(key_ref);
  	kleave(" = -EINPROGRESS [%d]", key_serial(key));
  	return -EINPROGRESS;
  
  alloc_failed:
  	mutex_unlock(&user->cons_lock);
  	*_key = NULL;
  	kleave(" = %ld", PTR_ERR(key));
  	return PTR_ERR(key);
  }
  
  /*
   * commence key construction
   */
  static struct key *construct_key_and_link(struct key_type *type,
  					  const char *description,
  					  const char *callout_info,
4a38e122e   David Howells   keys: allow the c...
330
  					  size_t callout_len,
76181c134   David Howells   KEYS: Make reques...
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
  					  void *aux,
  					  struct key *dest_keyring,
  					  unsigned long flags)
  {
  	struct key_user *user;
  	struct key *key;
  	int ret;
  
  	user = key_user_lookup(current->fsuid);
  	if (!user)
  		return ERR_PTR(-ENOMEM);
  
  	ret = construct_alloc_key(type, description, dest_keyring, flags, user,
  				  &key);
  	key_user_put(user);
  
  	if (ret == 0) {
4a38e122e   David Howells   keys: allow the c...
348
  		ret = construct_key(key, callout_info, callout_len, aux);
76181c134   David Howells   KEYS: Make reques...
349
350
351
352
353
354
355
356
357
358
359
  		if (ret < 0)
  			goto construction_failed;
  	}
  
  	return key;
  
  construction_failed:
  	key_negate_and_link(key, key_negative_timeout, NULL, NULL);
  	key_put(key);
  	return ERR_PTR(ret);
  }
3e30148c3   David Howells   [PATCH] Keys: Mak...
360

3e30148c3   David Howells   [PATCH] Keys: Mak...
361
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
363
364
   * request a key
   * - search the process's keyrings
   * - check the list of keys being created or updated
3e30148c3   David Howells   [PATCH] Keys: Mak...
365
366
   * - call out to userspace for a key if supplementary info was provided
   * - cache the key in an appropriate keyring
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
367
   */
3e30148c3   David Howells   [PATCH] Keys: Mak...
368
369
  struct key *request_key_and_link(struct key_type *type,
  				 const char *description,
4a38e122e   David Howells   keys: allow the c...
370
371
  				 const void *callout_info,
  				 size_t callout_len,
4e54f0854   David Howells   [PATCH] Keys: All...
372
  				 void *aux,
7e047ef5f   David Howells   [PATCH] keys: sor...
373
374
  				 struct key *dest_keyring,
  				 unsigned long flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
375
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
376
  	struct key *key;
664cceb00   David Howells   [PATCH] Keys: Add...
377
  	key_ref_t key_ref;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378

4a38e122e   David Howells   keys: allow the c...
379
380
  	kenter("%s,%s,%p,%zu,%p,%p,%lx",
  	       type->name, description, callout_info, callout_len, aux,
4e54f0854   David Howells   [PATCH] Keys: All...
381
  	       dest_keyring, flags);
3e30148c3   David Howells   [PATCH] Keys: Mak...
382

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
  	/* search all the process keyrings for a key */
664cceb00   David Howells   [PATCH] Keys: Add...
384
385
  	key_ref = search_process_keyrings(type, description, type->match,
  					  current);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
386

664cceb00   David Howells   [PATCH] Keys: Add...
387
388
  	if (!IS_ERR(key_ref)) {
  		key = key_ref_to_ptr(key_ref);
76181c134   David Howells   KEYS: Make reques...
389
  	} else if (PTR_ERR(key_ref) != -EAGAIN) {
e231c2ee6   David Howells   Convert ERR_PTR(P...
390
  		key = ERR_CAST(key_ref);
76181c134   David Howells   KEYS: Make reques...
391
  	} else  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
392
393
394
395
396
  		/* the search failed, but the keyrings were searchable, so we
  		 * should consult userspace if we can */
  		key = ERR_PTR(-ENOKEY);
  		if (!callout_info)
  			goto error;
76181c134   David Howells   KEYS: Make reques...
397
  		key = construct_key_and_link(type, description, callout_info,
4a38e122e   David Howells   keys: allow the c...
398
399
  					     callout_len, aux, dest_keyring,
  					     flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
400
  	}
3e30148c3   David Howells   [PATCH] Keys: Mak...
401
402
  error:
  	kleave(" = %p", key);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
403
  	return key;
76181c134   David Howells   KEYS: Make reques...
404
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
405

76181c134   David Howells   KEYS: Make reques...
406
407
408
409
410
411
  /*
   * wait for construction of a key to complete
   */
  int wait_for_key_construction(struct key *key, bool intr)
  {
  	int ret;
3e30148c3   David Howells   [PATCH] Keys: Mak...
412

76181c134   David Howells   KEYS: Make reques...
413
414
415
416
417
418
419
420
  	ret = wait_on_bit(&key->flags, KEY_FLAG_USER_CONSTRUCT,
  			  intr ? key_wait_bit_intr : key_wait_bit,
  			  intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
  	if (ret < 0)
  		return ret;
  	return key_validate(key);
  }
  EXPORT_SYMBOL(wait_for_key_construction);
3e30148c3   David Howells   [PATCH] Keys: Mak...
421

3e30148c3   David Howells   [PATCH] Keys: Mak...
422
423
424
425
426
  /*
   * request a key
   * - search the process's keyrings
   * - check the list of keys being created or updated
   * - call out to userspace for a key if supplementary info was provided
76181c134   David Howells   KEYS: Make reques...
427
   * - waits uninterruptible for creation to complete
3e30148c3   David Howells   [PATCH] Keys: Mak...
428
429
430
431
432
   */
  struct key *request_key(struct key_type *type,
  			const char *description,
  			const char *callout_info)
  {
76181c134   David Howells   KEYS: Make reques...
433
  	struct key *key;
4a38e122e   David Howells   keys: allow the c...
434
  	size_t callout_len = 0;
76181c134   David Howells   KEYS: Make reques...
435
  	int ret;
4a38e122e   David Howells   keys: allow the c...
436
437
438
439
  	if (callout_info)
  		callout_len = strlen(callout_info);
  	key = request_key_and_link(type, description, callout_info, callout_len,
  				   NULL, NULL, KEY_ALLOC_IN_QUOTA);
76181c134   David Howells   KEYS: Make reques...
440
441
442
443
444
445
446
447
448
  	if (!IS_ERR(key)) {
  		ret = wait_for_key_construction(key, false);
  		if (ret < 0) {
  			key_put(key);
  			return ERR_PTR(ret);
  		}
  	}
  	return key;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
449
  EXPORT_SYMBOL(request_key);
4e54f0854   David Howells   [PATCH] Keys: All...
450

4e54f0854   David Howells   [PATCH] Keys: All...
451
452
453
454
455
  /*
   * request a key with auxiliary data for the upcaller
   * - search the process's keyrings
   * - check the list of keys being created or updated
   * - call out to userspace for a key if supplementary info was provided
76181c134   David Howells   KEYS: Make reques...
456
   * - waits uninterruptible for creation to complete
4e54f0854   David Howells   [PATCH] Keys: All...
457
458
459
   */
  struct key *request_key_with_auxdata(struct key_type *type,
  				     const char *description,
4a38e122e   David Howells   keys: allow the c...
460
461
  				     const void *callout_info,
  				     size_t callout_len,
4e54f0854   David Howells   [PATCH] Keys: All...
462
463
  				     void *aux)
  {
76181c134   David Howells   KEYS: Make reques...
464
465
  	struct key *key;
  	int ret;
4a38e122e   David Howells   keys: allow the c...
466
467
  	key = request_key_and_link(type, description, callout_info, callout_len,
  				   aux, NULL, KEY_ALLOC_IN_QUOTA);
76181c134   David Howells   KEYS: Make reques...
468
469
470
471
472
473
474
475
476
477
  	if (!IS_ERR(key)) {
  		ret = wait_for_key_construction(key, false);
  		if (ret < 0) {
  			key_put(key);
  			return ERR_PTR(ret);
  		}
  	}
  	return key;
  }
  EXPORT_SYMBOL(request_key_with_auxdata);
4e54f0854   David Howells   [PATCH] Keys: All...
478

76181c134   David Howells   KEYS: Make reques...
479
480
481
482
483
484
485
486
  /*
   * request a key (allow async construction)
   * - search the process's keyrings
   * - check the list of keys being created or updated
   * - call out to userspace for a key if supplementary info was provided
   */
  struct key *request_key_async(struct key_type *type,
  			      const char *description,
4a38e122e   David Howells   keys: allow the c...
487
488
  			      const void *callout_info,
  			      size_t callout_len)
76181c134   David Howells   KEYS: Make reques...
489
  {
4a38e122e   David Howells   keys: allow the c...
490
491
492
  	return request_key_and_link(type, description, callout_info,
  				    callout_len, NULL, NULL,
  				    KEY_ALLOC_IN_QUOTA);
76181c134   David Howells   KEYS: Make reques...
493
494
  }
  EXPORT_SYMBOL(request_key_async);
4e54f0854   David Howells   [PATCH] Keys: All...
495

76181c134   David Howells   KEYS: Make reques...
496
497
498
499
500
501
502
503
  /*
   * request a key with auxiliary data for the upcaller (allow async construction)
   * - search the process's keyrings
   * - check the list of keys being created or updated
   * - call out to userspace for a key if supplementary info was provided
   */
  struct key *request_key_async_with_auxdata(struct key_type *type,
  					   const char *description,
4a38e122e   David Howells   keys: allow the c...
504
505
  					   const void *callout_info,
  					   size_t callout_len,
76181c134   David Howells   KEYS: Make reques...
506
507
  					   void *aux)
  {
4a38e122e   David Howells   keys: allow the c...
508
509
  	return request_key_and_link(type, description, callout_info,
  				    callout_len, aux, NULL, KEY_ALLOC_IN_QUOTA);
76181c134   David Howells   KEYS: Make reques...
510
511
  }
  EXPORT_SYMBOL(request_key_async_with_auxdata);